New Upstream Snapshot - gm-assistant

Ready changes

Summary

Merged new upstream version: 1.2.4+git20220326.1.92b4b98 (was: 1.2.4).

Resulting package

Built on 2023-01-19T01:38 (took 14m38s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-snapshots gm-assistant-dbgsymapt install -t fresh-snapshots gm-assistant-docapt install -t fresh-snapshots gm-assistant

Lintian Result

Diff

diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index a939cdc..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,19 +0,0 @@
-gm-assistant
-*.pro
-*.conf
-*.desktop
-*.entitlements
-Makefile
-ui_*
-qrc_*
-.*
-*.o
-moc_*
-*.qm
-*.log
-documentation/
-doc/dev/
-*.pdf
-*.aux
-*.out
-*.toc
diff --git a/CHANGELOG b/CHANGELOG
index 4065c3a..fa1eaf2 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,15 @@
+Changes in version 1.3.0
+* Notes
+    - new item type containing a note
+    - note associated with every character
+    - tabs for the differents notes
+* Release notes now available in the Help menu
+* Dice simulator:
+    - limit number of dice increased to 100
+    - additional information about the rolled dice (sum, min, max, etc.)
+* Combat manager:
+    - round counter added
+
 Changes in version 1.2.4
 * HTML version of the user guide
 * new AppStream metadata file
@@ -41,8 +53,7 @@ Changes in version 1.2.0
     - metadata added to the scenario
     - possibility to move characters and properties
     - new tools: dice simulator and combat manager
-    - scenario file format changed to an archive containing all audio and
- image files
+    - scenario file format changed to an archive containing all audio and image files
     - save of the expanded/collapsed state of items
     - confirmation before closing
     - possibility to choose the language of the interface
@@ -59,7 +70,7 @@ Changes in version 1.2.0
 
 Changes in version 1.1.9
 - reorganization of the info dialog window to fit in low-resolution screens
-- auto-scrolling in table/tree widgets when adding/editing skill/character 
+- auto-scrolling in table/tree widgets when adding/editing skill/character
 - new options added to the configure script
 - default working directory for Windows
 - new icon for the edition in table/tree widget
@@ -72,8 +83,7 @@ Changes in version 1.1.9
 Changes in version 1.1.8
 - Interface menu renamed View
 - ambiguous shortcut to add an item modified (now Ins)
-- crash when trying to play music or move the slider without a selected file
- fixed
+- crash when trying to play music or move the slider without a selected file fixed
 - various interface bugs fixed
 
 Changes in version 1.1.7
@@ -93,8 +103,7 @@ Changes in version 1.1.7
 Changes in version 1.1.6
 - depencies modified to work on Fedora
 - error message added when a music file cannot be read
-- display of a default image when an image file cannot be read replaced by
- an error message
+- display of a default image when an image file cannot be read replaced by an error message
 - useless source files deleted
 
 Changes in version 1.1.5
@@ -134,7 +143,7 @@ Changes in version 1.0.15
 - resizing bug in table widget fixed
 
 Changes in version 1.0.14
-- the slider now accepts wheel events and clicks 
+- the slider now accepts wheel events and clicks
 - modification of the child-adding method of trees
 - now requires SDL_mixer version >= 1.2.12
 - reset of the sound engine when loading a game file
@@ -144,8 +153,7 @@ Changes in version 1.0.13
 
 Changes in version 1.0.12
 - bug when right-clicking in the table widget fixed
-- restoration of the default behaviour of the table widget header when
- right-clicking
+- restoration of the default behaviour of the table widget header when right-clicking
 
 Changes in version 1.0.11
 - bug in finding translation files in non-linux systems fixed
@@ -158,8 +166,7 @@ Changes in version 1.0.9:
 - bug when adding a new item at the root of a tree fixed
 
 Changes in version 1.0.8:
-- crash when moving an item into another (due to creation with bad parent)
- fixed (I hope definitively!)
+- crash when moving an item into another (due to creation with bad parent) fixed
 
 Changes in version 1.0.7:
 - crash when moving an item created with child (or into one) fixed
@@ -168,23 +175,20 @@ Changes in version 1.0.7:
 
 Changes in version 1.0.6:
 * Trees:
-	- crash when moving an item into a previously moved one fixed
-	- resize of the items when moved
+    - crash when moving an item into a previously moved one fixed
+    - resize of the items when moved
 * Others
-	- path (translations ans examples) issue on Linux when using a launcher
- solved
-	
+    - path (translations ans examples) issue on Linux when using a launcher solved
+
 Changes in version 1.0.5:
 - crash when typing 'Del' while editing an item fixed
 
 Changes in version 1.0.4:
 * Uninstallation:
-	- 'make install' creates a log file which contains the list of the files
-	to remove during uninstallation
-	- 'make uninstall' removes only those files and the empty directories
-	instead of a raw 'rm -r *'
+    - 'make install' creates a log file which contains the list of the files to remove during uninstallation
+    - 'make uninstall' removes only those files and the empty directories instead of a raw 'rm -r *'
 * Others:
-	- the configure script displays the list of linked libraries
+    - the configure script displays the list of linked libraries
 
 Changes in version 1.0.3:
 - crash when moving an item in a following branch fixed
@@ -195,8 +199,8 @@ Changes in version 1.0.2:
 
 Changes in version 1.0.1:
 * Trees:
-	- drag & drop bug fixed
-	- selected items can now be dragged
-	- right-clicking an item selects it
+    - drag & drop bug fixed
+    - selected items can now be dragged
+    - right-clicking an item selects it
 * Others:
-	- non-player characters can be added in the table
+    - non-player characters can be added in the table
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ca8f70f..9435687 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,8 +24,8 @@ project (${PROJECT_NAME})
 
 # handling version
 set (VERSION_MAJOR 1)
-set (VERSION_MINOR 2)
-set (VERSION_PATCH 4)
+set (VERSION_MINOR 3)
+set (VERSION_PATCH 0)
 configure_file(sources/engine/Version.h.in Version.h)
 
 # options
@@ -51,6 +51,7 @@ set (PROJECT_SOURCES
     sources/engine/FileMapping.cpp
     sources/engine/IOConfig.cpp
     sources/engine/Metadata.cpp
+    sources/engine/Note.cpp
     sources/engine/PropertyList.cpp
     sources/engine/Scenario.cpp
     sources/engine/Tree.cpp
@@ -59,6 +60,7 @@ set (PROJECT_SOURCES
     sources/engine/items/ImageItem.cpp
     sources/engine/items/Item.cpp
     sources/engine/items/ItemFactory.cpp
+    sources/engine/items/NoteItem.cpp
     sources/engine/items/SoundItem.cpp
     sources/engine/modifications/CharacterModification.cpp
     sources/engine/modifications/MetadataModification.cpp
@@ -67,7 +69,9 @@ set (PROJECT_SOURCES
     sources/engine/modifications/NoteModification.cpp
     sources/engine/modifications/TreeModification.cpp
     sources/widgets/QCustomHeaderView.cpp
+    sources/widgets/QCustomTabBar.cpp
     sources/widgets/QCustomTableWidget.cpp
+    sources/widgets/QCustomTabWidget.cpp
     sources/widgets/QCustomTextEdit.cpp
     sources/widgets/QCustomTreeWidget.cpp
     sources/widgets/QCustomTreeWidgetItem.cpp
@@ -80,6 +84,8 @@ set (PROJECT_SOURCES
     sources/windows/ItemDialog.cpp
     sources/windows/MainWindow.cpp
     sources/windows/MetadataDialog.cpp
+    sources/windows/ReleaseNotesDialog.cpp
+    sources/windows/RenameNoteDialog.cpp
     sources/windows/SelectCharacterDialog.cpp)
 set (PROJECT_FORMS
     sources/windows/AboutDialog.ui
@@ -90,6 +96,8 @@ set (PROJECT_FORMS
     sources/windows/ItemDialog.ui
     sources/windows/MainWindow.ui
     sources/windows/MetadataDialog.ui
+    sources/windows/ReleaseNotesDialog.ui
+    sources/windows/RenameNoteDialog.ui
     sources/windows/SelectCharacterDialog.ui)
 
 # find libraries
@@ -182,6 +190,8 @@ if (${Qt5LinguistTools_FOUND})
 endif()
 install(FILES doc/gm-assistant.6
     DESTINATION ${MAN_DIR}/man6)
+install(FILES CHANGELOG
+    DESTINATION ${DATA_DIR})
 
 # metainfo file
 set (METAINFO_ID fr.free.gmassistant)
diff --git a/COPYRIGHT b/COPYRIGHT
index 006f8f7..8ac7b6a 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -2,10 +2,10 @@ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 Upstream-Contact: Vincent Prat <vinceprat@free.fr>
 Source: http://vivicoder.github.com/GM-Assistant
 License: GPL-3.0+
-Copyright: 2011-2013 Vincent Prat & Simon Nicolas
+Copyright: 2011-2016 Vincent Prat & Simon Nicolas
 
 Files: *
-Copyright: 2011-2013 Vincent Prat & Simon Nicolas
+Copyright: 2011-2016 Vincent Prat & Simon Nicolas
 License: GPL-3.0+
 
 Files: data/images/*
@@ -22,6 +22,7 @@ Comment:
  son.svg:       http://openclipart.org/detail/24063
  speaker.svg:   http://openclipart.org/detail/168846
  stop.svg:      http://openclipart.org/detail/57745
+ text.svg:      https://openclipart.org/detail/237988
  uncheck.svg:   http://openclipart.org/detail/33685
  up.svg:        http://openclipart.org/detail/12115
 
diff --git a/data/images/text.svg b/data/images/text.svg
new file mode 100644
index 0000000..687595f
--- /dev/null
+++ b/data/images/text.svg
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 width="470.586px" height="470.586px" viewBox="0 0 470.586 470.586" style="enable-background:new 0 0 470.586 470.586;"
+	 xml:space="preserve">
+<g>
+	<path d="M327.081,0H90.234C74.331,0,61.381,12.959,61.381,28.859v412.863c0,15.924,12.95,28.863,28.853,28.863H380.35
+		c15.917,0,28.855-12.939,28.855-28.863V89.234L327.081,0z M333.891,43.184l35.996,39.121h-35.996V43.184z M384.972,441.723
+		c0,2.542-2.081,4.629-4.635,4.629H90.234c-2.55,0-4.619-2.087-4.619-4.629V28.859c0-2.548,2.069-4.613,4.619-4.613h219.411v70.181
+		c0,6.682,5.443,12.099,12.129,12.099h63.198V441.723z M128.364,128.89H334.15c5.013,0,9.079,4.066,9.079,9.079
+		c0,5.013-4.066,9.079-9.079,9.079H128.364c-5.012,0-9.079-4.066-9.079-9.079C119.285,132.957,123.352,128.89,128.364,128.89z
+		 M343.229,198.98c0,5.012-4.066,9.079-9.079,9.079H128.364c-5.012,0-9.079-4.066-9.079-9.079s4.067-9.079,9.079-9.079H334.15
+		C339.163,189.901,343.229,193.968,343.229,198.98z M343.229,257.993c0,5.013-4.066,9.079-9.079,9.079H128.364
+		c-5.012,0-9.079-4.066-9.079-9.079s4.067-9.079,9.079-9.079H334.15C339.163,248.914,343.229,252.98,343.229,257.993z
+		 M343.229,318.011c0,5.013-4.066,9.079-9.079,9.079H128.364c-5.012,0-9.079-4.066-9.079-9.079s4.067-9.079,9.079-9.079H334.15
+		C339.163,308.932,343.229,312.998,343.229,318.011z"/>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/debian/changelog b/debian/changelog
index 288ceab..62337dd 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+gm-assistant (1.2.4+git20220326.1.92b4b98-1) UNRELEASED; urgency=low
+
+  * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Thu, 19 Jan 2023 01:28:47 -0000
+
 gm-assistant (1.2.4-1) unstable; urgency=medium
 
   * New upstream release
diff --git a/ressource.qrc b/ressource.qrc
index 87929ea..b7b63fe 100644
--- a/ressource.qrc
+++ b/ressource.qrc
@@ -1,6 +1,7 @@
 <RCC>
   <qresource>
     <file>data/images/GMA.svg</file>
+    <file>data/images/text.svg</file>
     <file>data/images/add.svg</file>
     <file>data/images/image.svg</file>
     <file>data/images/check.svg</file>
diff --git a/sources/engine/Character.cpp b/sources/engine/Character.cpp
index 1694d17..4c6463b 100644
--- a/sources/engine/Character.cpp
+++ b/sources/engine/Character.cpp
@@ -25,10 +25,18 @@ using namespace std;
 
 // constructors
 
-Character::Character(const string &name, const string &shortDescription): sName(name), sShort(shortDescription)
+Character::Character(const string &name, const string &shortDescription): sName(name), sShort(shortDescription), pNote(new Note(name))
 {
 }
 
+Character::~Character()
+{
+    if (pNote)
+    {
+        delete pNote;
+    }
+}
+
 std::string& Character::property(int index)
 {
     if (index < 0 || (unsigned int)index >= vProperties.size())
@@ -50,6 +58,12 @@ void Character::toXML(const IOConfig &config, Poco::XML::Element *root) const
     using namespace Poco::XML;
 
     Document *document = root->ownerDocument();
+    if (config.hasNotes())
+    {
+        Element *tmp = document->createElement("note");
+        root->appendChild(tmp);
+        pNote->toXML(tmp);
+    }
     for (vector<std::string>::const_iterator it = vProperties.begin(); it != vProperties.end(); it++)
     {
         Element *tmp = document->createElement(config.propertyName());
@@ -62,6 +76,14 @@ void Character::fromXML(const IOConfig &config, const Poco::XML::Element *root)
 {
     using namespace Poco::XML;
 
+    if (config.hasNotes())
+    {
+        Element *element = root->getChildElement("note");
+        if (element)
+        {
+            pNote->fromXML(element);
+        }
+    }
     clearProperties();
     NodeList *list = root->getElementsByTagName(config.propertyName());
     for (int i = 0; i < list->length(); i++)
diff --git a/sources/engine/Character.h b/sources/engine/Character.h
index b87551d..e550bba 100644
--- a/sources/engine/Character.h
+++ b/sources/engine/Character.h
@@ -22,6 +22,7 @@
 #include <vector>
 #include <Poco/DOM/Element.h>
 #include "IOConfig.h"
+#include "Note.h"
 
 //! Character (PC or NPC)
 class Character
@@ -32,6 +33,8 @@ class Character
         std::string sShort;
         //! Underlying vector
         std::vector<std::string> vProperties;
+        //! Note associated with the character
+        Note* pNote;
     public:
         // iterator
         class PropertyIterator: public std::vector<std::string>::const_iterator
@@ -46,6 +49,10 @@ class Character
          * \param shortDescription Short description (typically player's name for PCs or group/race for NPCs)
          */
         Character(const std::string &name, const std::string &shortDescription);
+        /*!
+         * \brief Destructor
+         */
+        ~Character();
         /*!
          * \brief XML saver
          * \param config IO configuration
@@ -100,6 +107,11 @@ class Character
          */
         bool moveProperty(int source, int destination);
         void clearProperties();
+        /*!
+         * \brief Getter for the note
+         * \return Note associated with the character
+         */
+        inline Note *note();
         // iterators
         PropertyIterator begin() const;
         PropertyIterator end() const;
@@ -125,4 +137,9 @@ void Character::setShortDescription(const std::string &shortDescription)
     sShort = shortDescription;
 }
 
+Note *Character::note()
+{
+    return pNote;
+}
+
 #endif
diff --git a/sources/engine/CharacterList.cpp b/sources/engine/CharacterList.cpp
index f73350d..50aef44 100644
--- a/sources/engine/CharacterList.cpp
+++ b/sources/engine/CharacterList.cpp
@@ -27,18 +27,24 @@ CharacterList::CharacterList()
 {
 }
 
+CharacterList::~CharacterList()
+{
+    clear();
+}
+
 void CharacterList::toXML(const IOConfig &config, Poco::XML::Element *root) const
 {
     using namespace Poco::XML;
 
     Document *document = root->ownerDocument();
-    for (vector<Character>::const_iterator it = vCharacters.begin(); it != vCharacters.end(); it++)
+    for (vector<Character*>::const_iterator it = vCharacters.begin(); it != vCharacters.end(); it++)
     {
         Element *tmp = document->createElement("character");
+        Character *character = *it;
         root->appendChild(tmp);
-        tmp->setAttribute("name", it->name());
-        tmp->setAttribute(config.descriptionName(), it->shortDescription());
-        it->toXML(config, tmp);
+        tmp->setAttribute("name", character->name());
+        tmp->setAttribute(config.descriptionName(), character->shortDescription());
+        character->toXML(config, tmp);
     }
 }
 
@@ -53,8 +59,8 @@ void CharacterList::fromXML(const IOConfig &config, const Poco::XML::Element *ro
         Element *elem = static_cast<Element*>(list->item(i));
         string name = elem->getAttribute("name");
         string shortDescription = elem->getAttribute(config.descriptionName());
-        Character character = Character(name, shortDescription);
-        character.fromXML(config, elem);
+        Character *character = new Character(name, shortDescription);
+        character->fromXML(config, elem);
         vCharacters.push_back(character);
     }
     list->release();
@@ -62,10 +68,14 @@ void CharacterList::fromXML(const IOConfig &config, const Poco::XML::Element *ro
 
 void CharacterList::clear()
 {
+    for (vector<Character*>::iterator it = vCharacters.begin(); it != vCharacters.end(); it++)
+    {
+        delete (*it);
+    }
     vCharacters.clear();
 }
 
-void CharacterList::add(const Character &character, int position)
+void CharacterList::add(Character *character, int position)
 {
     // if out if bounds, just push_back
     if (position<0 || (unsigned int)position > vCharacters.size())
@@ -102,7 +112,7 @@ bool CharacterList::move(int source, int destination)
         return false;
     }
     // character to move
-    Character& character = vCharacters[source];
+    Character *character = vCharacters[source];
     if (source < destination)
     {
         destination++;
@@ -116,7 +126,7 @@ bool CharacterList::move(int source, int destination)
     return true;
 }
 
-Character& CharacterList::operator[](int index)
+Character* CharacterList::operator[](int index)
 {
     if (index<0 || (unsigned int)index >= vCharacters.size())
     {
@@ -147,11 +157,11 @@ CharacterList::iterator CharacterList::end()
 
 // iterators' methods
 
-CharacterList::iterator::iterator(const vector<Character>::iterator &it): vector<Character>::iterator(it)
+CharacterList::iterator::iterator(const vector<Character*>::iterator &it): vector<Character*>::iterator(it)
 {
 }
 
-CharacterList::const_iterator::const_iterator(const vector<Character>::const_iterator &it): vector<Character>::const_iterator(it)
+CharacterList::const_iterator::const_iterator(const vector<Character*>::const_iterator &it): vector<Character*>::const_iterator(it)
 {
 }
 
diff --git a/sources/engine/CharacterList.h b/sources/engine/CharacterList.h
index 0f89219..1c151cf 100644
--- a/sources/engine/CharacterList.h
+++ b/sources/engine/CharacterList.h
@@ -28,24 +28,26 @@ class CharacterList
 {
     private:
         //! Underlying character vector
-        std::vector<Character> vCharacters;
+        std::vector<Character*> vCharacters;
     public:
         // iterators
-        class const_iterator: public std::vector<Character>::const_iterator
+        class const_iterator: public std::vector<Character*>::const_iterator
         {
             public:
                 // constructor
-                const_iterator(const std::vector<Character>::const_iterator &it);
+                const_iterator(const std::vector<Character*>::const_iterator &it);
         };
-        class iterator: public std::vector<Character>::iterator
+        class iterator: public std::vector<Character*>::iterator
         {
             public:
                 // constructor
-                iterator(const std::vector<Character>::iterator &it);
+                iterator(const std::vector<Character*>::iterator &it);
                 iterator(const const_iterator &it);
         };
         // constructor
         CharacterList();
+        //! Destructor
+        ~CharacterList();
         /*!
          * \brief XML saver
          * \param config IO configuration
@@ -61,14 +63,23 @@ class CharacterList
         /*!
          * \brief Getter of the characters
          * \param index Index of the character
-         * \return Reference to the character at the given index
+         * \return Pointer to the character at the given index
+         * \throw std::out_of_range Thrown when the index does not correspond to any character
          */
-        Character& operator[](int index);
-        // populating
-        void add(const Character &character, int position=-1);
+        Character* operator[](int index);
         /*!
-         * \brief Remove a character
+         * \brief Method to add a character
+         * \param character Pointer to the character to add
+         * \param position Position where to add the character
+         *
+         * If position is -1, the character is added at the end.
+         */
+        void add(Character *character, int position=-1);
+        /*!
+         * \brief Method to remove a character
          * \param index Index of the character to remove
+         *
+         * This method does not destroy the character.
          */
         void remove(int index);
         /*!
@@ -78,6 +89,11 @@ class CharacterList
          * \return True if the move has been made, false otherwise
          */
         bool move(int source, int destination);
+        /*!
+         * \brief Method to clear the list
+         *
+         * Clear the lists and destroys all characters
+         */
         void clear();
         // iterators
         const_iterator begin() const;
diff --git a/sources/engine/IOConfig.cpp b/sources/engine/IOConfig.cpp
index 47a2221..dadebdb 100644
--- a/sources/engine/IOConfig.cpp
+++ b/sources/engine/IOConfig.cpp
@@ -56,6 +56,14 @@ IOConfig::IOConfig(const Version &version): vVersion(version), bValid(true)
         bArchived = true;
         sDescriptionName = "description";
     }
+    if (vVersion < Version(1, 3))
+    {
+        bHasNotes = false;
+    }
+    else
+    {
+        bHasNotes = true;
+    }
 }
 
 IOConfig IOConfig::detect(const string &fileName, const Element *root, bool isArchived)
@@ -129,5 +137,9 @@ IOConfig IOConfig::detect(const string &fileName, const Element *root, bool isAr
     {
         res.setDescriptionName("playername");
     }
+    if (root->getNodeByPath("//item[@type='note']"))
+    {
+        res.setHasNotes(true);
+    }
     return res;
 }
diff --git a/sources/engine/IOConfig.h b/sources/engine/IOConfig.h
index 804b56e..433a27a 100644
--- a/sources/engine/IOConfig.h
+++ b/sources/engine/IOConfig.h
@@ -54,7 +54,9 @@ class IOConfig
         //! Flag of availability of metadata
         bool bHasMetadata;
         //! Flag of archive format
-        bool bArchived; 
+        bool bArchived;
+        // Flag of availability of note elements
+        bool bHasNotes;
         //! Temporary directory
         std::string sTempDir;
     public:
@@ -158,9 +160,9 @@ class IOConfig
         inline bool hasMetadata() const;
         /*!
          * \brief Setter for the flag of availability of metadata
-         * \param hadMetadata New flag of availability of metadata
+         * \param hasMetadata New flag of availability of metadata
          */
-        inline void setHasMetadata(bool hadMetadata);
+        inline void setHasMetadata(bool hasMetadata);
         /*!
          * \brief Getter for the flag of archive format
          * \return Flag of archive format
@@ -186,6 +188,16 @@ class IOConfig
          * \param descriptionName New name of the short description attribute
          */
         inline void setDescriptionName(const std::string &descriptionName);
+        /*!
+         * \brief Getter for the flag of availability of notes
+         * \return Flag of availability of notes
+         */
+        inline bool hasNotes() const;
+        /*!
+         * \brief Setter for the flag of availability of notes
+         * \param hasNotes Flag of availability of notes
+         */
+        inline void setHasNotes(bool hasNotes);
 };
 
 std::string IOConfig::rootName() const
@@ -343,4 +355,18 @@ void IOConfig::setDescriptionName(const std::string &descriptionName)
     }
 }
 
+bool IOConfig::hasNotes() const
+{
+    return bHasNotes;
+}
+
+void IOConfig::setHasNotes(bool hasNotes)
+{
+    if (hasNotes != bHasNotes)
+    {
+        bHasNotes = hasNotes;
+        bValid = false;
+    }
+}
+
 #endif
diff --git a/sources/engine/Note.cpp b/sources/engine/Note.cpp
new file mode 100644
index 0000000..4bc2d12
--- /dev/null
+++ b/sources/engine/Note.cpp
@@ -0,0 +1,54 @@
+/*************************************************************************
+* Copyright © 2016-2020 Vincent Prat & Simon Nicolas
+*
+* 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, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*************************************************************************/
+
+#include "Note.h"
+#include "Item.h"
+#include <Poco/DOM/Document.h>
+#include <Poco/DOM/Text.h>
+
+using namespace std;
+
+Note::Note(const string &title, const string &text, bool visible): sTitle(title), sText(text), bVisible(visible)
+{
+}
+
+void Note::fromXML(const Poco::XML::Element *root)
+{
+    using namespace Poco::XML;
+
+    sTitle = root->getAttribute("title");
+    // visibility
+    string attr = root->getAttribute("visible");
+    bVisible = false;
+    if (!attr.empty())
+    {
+        bVisible = Item::strToBool(attr);
+    }
+    // text
+    sText = root->innerText();
+}
+
+void Note::toXML(Poco::XML::Element *root) const
+{
+    using namespace Poco::XML;
+
+    root->setAttribute("title", sTitle);
+    root->setAttribute("visible", Item::boolToStr(bVisible));
+    Document *document = root->ownerDocument();
+    root->appendChild(document->createTextNode(sText));
+}
diff --git a/sources/engine/Note.h b/sources/engine/Note.h
new file mode 100644
index 0000000..9a1d57b
--- /dev/null
+++ b/sources/engine/Note.h
@@ -0,0 +1,119 @@
+/*************************************************************************
+* Copyright © 2016-2020 Vincent Prat & Simon Nicolas
+*
+* 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, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*************************************************************************/
+
+#ifndef HEADER_NOTE
+#define HEADER_NOTE
+
+#include <string>
+#include <Poco/DOM/Element.h>
+
+/*!
+ * \brief Text note
+ */
+class Note
+{
+    public:
+        /*!
+         * \brief Default constructor
+         * \param title Title of the note
+         * \param text Text of the note
+         * \param visible Flag that indicates if the note is visible
+         */
+        Note(const std::string &title = "", const std::string &text = "", bool visible = false);
+        /*!
+         * \brief Getter for the title
+         * \return Title of the note
+         */
+        inline std::string title() const;
+        /*!
+         * \brief Setter for the title
+         * \param title New title
+         */
+        inline void setTitle(const std::string &title);
+        /*!
+         * \brief Getter for the text
+         * \return Reference to the text
+         */
+        inline std::string& text();
+        /*!
+         * \brief Const getter for the text
+         * \return Text
+         */
+        inline const std::string& text() const;
+        /*!
+         * \brief Getter for the visibility
+         * \return Visibility of the note
+         */
+        inline bool visible() const;
+        /*!
+         * \brief Setter for the visibility
+         * \param visible New visibility
+         */
+        inline void setVisible(bool visible);
+        /*!
+         * \brief XML loader
+         * \param root Root of the XML tree
+         */
+        void fromXML(const Poco::XML::Element *root);
+        /*!
+         * \brief XML saver
+         * \param root Root of the XML tree
+         */
+        void toXML(Poco::XML::Element *root) const;
+    private:
+        //! Title
+        std::string sTitle;
+        //! Text
+        std::string sText;
+        //! Visibility
+        bool bVisible;
+};
+
+// inline methods
+
+std::string Note::title() const
+{
+    return sTitle;
+}
+
+void Note::setTitle(const std::string &title)
+{
+    sTitle = title;
+}
+
+bool Note::visible() const
+{
+    return bVisible;
+}
+
+void Note::setVisible(bool visible)
+{
+    bVisible = visible;
+}
+
+std::string& Note::text()
+{
+    return sText;
+}
+
+const std::string& Note::text() const
+{
+    return sText;
+}
+
+#endif
diff --git a/sources/engine/Scenario.cpp b/sources/engine/Scenario.cpp
index 541f9ae..fb3eea1 100644
--- a/sources/engine/Scenario.cpp
+++ b/sources/engine/Scenario.cpp
@@ -161,7 +161,7 @@ void Scenario::fromFile(const std::string &fileName, bool checkFiles)
     }
     else
     {
-        sNotes = element->innerText();
+        nMain = Note("", element->innerText());
     }
     element = root->getChildElement(ioConfig.propertiesName());
     if (!element)
@@ -236,7 +236,7 @@ void Scenario::toFile(const string &fileName) const
     tPlot.toXML(ioConfig, tmp, fileMapping);
     tmp = document->createElement("notes");
     root->appendChild(tmp);
-    tmp->appendChild(document->createTextNode(sNotes));
+    tmp->appendChild(document->createTextNode(nMain.text()));
     tmp = document->createElement(ioConfig.propertiesName());
     root->appendChild(tmp);
     lProperties.toXML(ioConfig, tmp);
@@ -296,39 +296,12 @@ void Scenario::toFile(const string &fileName) const
     document->release();
 }
 
-// accessors
-
-Tree& Scenario::plot()
-{
-    return tPlot;
-}
-
-string& Scenario::notes()
-{
-    return sNotes;
-}
-
-Tree& Scenario::history()
-{
-    return tHistory;
-}
-
-Tree& Scenario::music()
-{
-    return tMusic;
-}
-
-Tree& Scenario::effects()
-{
-    return tEffects;
-}
-
 // methods
 
 void Scenario::clear()
 {
     tPlot.clear();
-    sNotes = "";
+    nMain = Note();
     tHistory.clear();
     tMusic.clear();
     tEffects.clear();
@@ -349,16 +322,6 @@ void Scenario::clear()
     }
 }
 
-CharacterList& Scenario::characters()
-{
-    return lCharacters;
-}
-
-PropertyList& Scenario::properties()
-{
-    return lProperties;
-}
-
 string Scenario::interfaceToString(UserInterface userInterface)
 {
     switch (userInterface)
@@ -386,28 +349,3 @@ Scenario::UserInterface Scenario::stringToInterface(const std::string& userInter
     else
         throw invalid_argument("Invalid user interface");
 }
-
-Scenario::UserInterface Scenario::userInterface() const
-{
-    return uiInterface;
-}
-
-void Scenario::setUserInterface(Scenario::UserInterface userInterface)
-{
-    uiInterface = userInterface;
-}
-
-IOConfig Scenario::configuration() const
-{
-    return ioConfig;
-}
-
-void Scenario::setVersion(const Version &version)
-{
-    ioConfig = IOConfig(version);
-}
-
-Metadata& Scenario::metadata()
-{
-    return mMetadata;
-}
diff --git a/sources/engine/Scenario.h b/sources/engine/Scenario.h
index 601b920..3c05a41 100644
--- a/sources/engine/Scenario.h
+++ b/sources/engine/Scenario.h
@@ -24,6 +24,7 @@
 #include "PropertyList.h"
 #include "IOConfig.h"
 #include "Metadata.h"
+#include "Note.h"
 
 /*!
  * \brief Game scenario
@@ -65,24 +66,52 @@ class Scenario
          * \param fileName Name of the file to be saved
          */
         void toFile(const std::string &fileName) const;
+        /*!
+         * \brief Getter for the main note of the scenario
+         * \return Main note
+         */
+        inline Note& mainNote();
         // accessors
-        Tree& plot();
-        std::string& notes();
-        Tree& history();
-        Tree& music();
-        Tree& effects();
-        PropertyList& properties();
-        CharacterList& characters();
+        /*!
+         * \brief Getter for the plot tree
+         * \return Plot tree
+         */
+        inline Tree& plot();
+        /*!
+         * \brief Getter for the history tree
+         * \return History tree
+         */
+        inline Tree& history();
+        /*!
+         * \brief Getter for the music tree
+         * \return Music tree
+         */
+        inline Tree& music();
+        /*!
+         * \brief Getter for the sound effect tree
+         * \return Sound effect tree
+         */
+        inline Tree& effects();
+        /*!
+         * \brief Getter for the property list
+         * \return Property list
+         */
+        inline PropertyList& properties();
+        /*!
+         * \brief Getter for the character list
+         * \return Character list
+         */
+        inline CharacterList& characters();
         /*!
          * \brief Get the user interface
          * \return Current user interface
          */
-        UserInterface userInterface() const;
+        inline UserInterface userInterface() const;
         /*!
          * \brief Set the user interface
          * \param userInterface New value of the user interface
          */
-        void setUserInterface(UserInterface userInterface);
+        inline void setUserInterface(UserInterface userInterface);
         //! Clear the current scenario
         void clear();
         /*!
@@ -101,28 +130,38 @@ class Scenario
          * \brief Getter for the IO configuration
          * \return IO configuration
          */
-        IOConfig configuration() const;
+        inline IOConfig configuration() const;
         /*!
          * \brief Setter for the IO configuration version
          * \param version Version
          *
          * Sets the IO configuration to the default for the given version
          */
-        void setVersion(const Version &version);
+        inline void setVersion(const Version &version);
         /*!
          * \brief Getter for the metadata
          * \return Metadata of the game
          */
-        Metadata& metadata();
+        inline Metadata& metadata();
         /*!
          * \brief Setter for the IO configuration
          * \param config IO configuration
          */
-        void setConfig(const IOConfig &config);
+        inline void setConfig(const IOConfig &config);
     private:
-        Tree tPlot, tHistory, tMusic, tEffects;
-        std::string sNotes;
+        //! Plot tree
+        Tree tPlot;
+        //! History tree
+        Tree tHistory;
+        //! Music tree
+        Tree tMusic;
+        //! Sound effect tree
+        Tree tEffects;
+        //! Main note
+        Note nMain;
+        //! Character list
         CharacterList lCharacters;
+        //! Property list
         PropertyList lProperties;
         //! User interface used by the game
         UserInterface uiInterface;
@@ -134,9 +173,71 @@ class Scenario
         std::string sTempDir;
 };
 
-inline void Scenario::setConfig(const IOConfig &config)
+// inline methods
+
+void Scenario::setConfig(const IOConfig &config)
 {
     ioConfig = config;
 }
 
+Tree& Scenario::plot()
+{
+    return tPlot;
+}
+
+Tree& Scenario::history()
+{
+    return tHistory;
+}
+
+Tree& Scenario::music()
+{
+    return tMusic;
+}
+
+Tree& Scenario::effects()
+{
+    return tEffects;
+}
+
+CharacterList& Scenario::characters()
+{
+    return lCharacters;
+}
+
+PropertyList& Scenario::properties()
+{
+    return lProperties;
+}
+
+Scenario::UserInterface Scenario::userInterface() const
+{
+    return uiInterface;
+}
+
+void Scenario::setUserInterface(Scenario::UserInterface userInterface)
+{
+    uiInterface = userInterface;
+}
+
+IOConfig Scenario::configuration() const
+{
+    return ioConfig;
+}
+
+void Scenario::setVersion(const Version &version)
+{
+    ioConfig = IOConfig(version);
+}
+
+Metadata& Scenario::metadata()
+{
+    return mMetadata;
+}
+
+Note& Scenario::mainNote()
+{
+    return nMain;
+}
+
 #endif
diff --git a/sources/engine/Version.cpp b/sources/engine/Version.cpp
index b50abc6..5ae8a6a 100644
--- a/sources/engine/Version.cpp
+++ b/sources/engine/Version.cpp
@@ -28,11 +28,16 @@ Version::Version(int major, int minor, int release): iMajor(major), iMinor(minor
 Version::Version(const string &version): iMajor(MAJOR_VERSION), iMinor(MINOR_VERSION), iRelease(RELEASE_VERSION)
 {
     istringstream buf(version);
-    buf >> iMajor;
-    buf.ignore(1);
-    buf >> iMinor;
-    buf.ignore(1);
-    buf >> iRelease;
+    int test;
+    buf >> test;
+    if (test)
+    {
+        iMajor = test;
+        buf.ignore(1);
+        buf >> iMinor;
+        buf.ignore(1);
+        buf >> iRelease;
+    }
 }
 
 string Version::shortVersion()
diff --git a/sources/engine/items/ImageItem.h b/sources/engine/items/ImageItem.h
index d16c603..af4a374 100644
--- a/sources/engine/items/ImageItem.h
+++ b/sources/engine/items/ImageItem.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2011-2013 Vincent Prat & Simon Nicolas
+* Copyright © 2011-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -39,9 +39,12 @@ class ImageItem: public FileItem
          * \brief Getter for the type of the item
          * \return Item::tImage
          */
-        Type type() const;
-        // archive subdirectory
-        std::string subdirectory() const;
+        Type type() const override;
+        /*!
+         * \brief Getter for the archive subdirectory corresponding to the item type
+         * \return Image subdirectory
+         */
+        std::string subdirectory() const override;
 };
 
 inline Item::Type ImageItem::type() const
diff --git a/sources/engine/items/Item.cpp b/sources/engine/items/Item.cpp
index 8b09628..f25f571 100644
--- a/sources/engine/items/Item.cpp
+++ b/sources/engine/items/Item.cpp
@@ -86,6 +86,11 @@ string Item::typeToStr(Type type, const IOConfig &config)
                             break;
                         }
         case tBasic:    return "basic"; break;
+        case tNote:     if (config.hasNotes())
+                        {
+                            return "note";
+                            break;
+                        }
     }
     return "";
 }
@@ -105,6 +110,7 @@ Item::Type Item::strToType(const string &name, const IOConfig &config)
     else if (name=="file") return tFile;
     else if (name=="sound") return tSound;
     else if (config.hasImages() && name == config.imageName()) return tImage;
+    else if (config.hasNotes() && name == "note") return tNote;
     else    throw Poco::XML::XMLException("Unrecognized \""+name+"\" item type");
 }
 
diff --git a/sources/engine/items/Item.h b/sources/engine/items/Item.h
index 96f5d91..854b797 100644
--- a/sources/engine/items/Item.h
+++ b/sources/engine/items/Item.h
@@ -44,7 +44,9 @@ class Item
             //! Item related to a sound file
             tSound,
             //! Item related to an image file
-            tImage
+            tImage,
+            //! Item associted with a note
+            tNote
         };
         /*!
          * \brief Constructor
diff --git a/sources/engine/items/ItemFactory.cpp b/sources/engine/items/ItemFactory.cpp
index aa8a851..17cbca3 100644
--- a/sources/engine/items/ItemFactory.cpp
+++ b/sources/engine/items/ItemFactory.cpp
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2011-2013 Vincent Prat & Simon Nicolas
+* Copyright © 2011-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -23,9 +23,10 @@ Item* ItemFactory::copyItem(Item *item)
     switch (item->type())
     {
         case Item::tBasic:  return new Item(*item); break;
-        case Item::tFile:   return new FileItem(*dynamic_cast<FileItem*>(item)); break;
-        case Item::tSound:  return new SoundItem(*dynamic_cast<SoundItem*>(item)); break;
-        case Item::tImage:  return new ImageItem(*dynamic_cast<ImageItem*>(item)); break;
+        case Item::tFile:   return new FileItem(*static_cast<FileItem*>(item)); break;
+        case Item::tSound:  return new SoundItem(*static_cast<SoundItem*>(item)); break;
+        case Item::tImage:  return new ImageItem(*static_cast<ImageItem*>(item)); break;
+        case Item::tNote:   return new NoteItem(*static_cast<NoteItem*>(item)); break;
     }
     return 0;
 }
@@ -38,6 +39,7 @@ Item* ItemFactory::createItem(Item::Type type, const std::string &content, Item:
         case Item::tFile:   return new FileItem(content,state,expanded); break;
         case Item::tSound:  return new SoundItem(content,state,expanded); break;
         case Item::tImage:  return new ImageItem(content,state,expanded); break;
+        case Item::tNote:   return new NoteItem(content,state,expanded); break;
     }
     return 0;
 }
diff --git a/sources/engine/items/ItemFactory.h b/sources/engine/items/ItemFactory.h
index 9995dc2..ab20e38 100644
--- a/sources/engine/items/ItemFactory.h
+++ b/sources/engine/items/ItemFactory.h
@@ -19,10 +19,12 @@
 #ifndef HEADER_ITEMFACTORY
 #define HEADER_ITEMFACTORY
 
+// also used to broadcast all item classes
 #include "Item.h"
 #include "FileItem.h"
 #include "SoundItem.h"
 #include "ImageItem.h"
+#include "NoteItem.h"
 
 /*!
  * \brief Item factory
diff --git a/sources/engine/items/NoteItem.cpp b/sources/engine/items/NoteItem.cpp
new file mode 100644
index 0000000..5bc6faf
--- /dev/null
+++ b/sources/engine/items/NoteItem.cpp
@@ -0,0 +1,65 @@
+/*************************************************************************
+* Copyright © 2016-2020 Vincent Prat & Simon Nicolas
+*
+* 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, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*************************************************************************/
+
+#include "NoteItem.h"
+#include <Poco/DOM/Document.h>
+
+using namespace std;
+
+NoteItem::NoteItem(const string &content, State state, bool expanded, Note *note): Item(content,state,expanded), pNote(note)
+{
+    if (!note)
+    {
+        pNote = new Note();
+    }
+}
+
+NoteItem::~NoteItem()
+{
+    if (pNote)
+    {
+        delete pNote;
+    }
+}
+
+void NoteItem::fromXML(const IOConfig &config, const Poco::XML::Element *root, bool)
+{
+    using namespace Poco::XML;
+
+    if (config.hasNotes())
+    {
+        Element *element  = root->getChildElement("note");
+        if (element)
+        {
+            pNote->fromXML(element);
+        }
+    }
+}
+
+void NoteItem::toXML(const IOConfig &config, Poco::XML::Element *root, FileMapping&)
+{
+    using namespace Poco::XML;
+
+    if (config.hasNotes())
+    {
+        Document *document = root->ownerDocument();
+        Element *tmp = document->createElement("note");
+        root->appendChild(tmp);
+        pNote->toXML(tmp);
+    }
+}
diff --git a/sources/engine/items/NoteItem.h b/sources/engine/items/NoteItem.h
new file mode 100644
index 0000000..4cfefa4
--- /dev/null
+++ b/sources/engine/items/NoteItem.h
@@ -0,0 +1,99 @@
+/*************************************************************************
+* Copyright © 2016-2020 Vincent Prat & Simon Nicolas
+*
+* 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, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*************************************************************************/
+
+#ifndef HEADER_NOTEITEM
+#define HEADER_NOTEITEM
+
+#include "Item.h"
+#include "Note.h"
+
+/*!
+ * \brief Item containing a note
+ */
+class NoteItem: public Item
+{
+    private:
+        /*!
+         * \brief Note associated with the item
+         */
+        Note *pNote;
+    public:
+        /*!
+         * \brief Setter for the note
+         * \param note New note
+         */
+        inline void setNote(Note *note);
+        /*!
+         * \brief Constructor
+         * \param content Content of the item
+         * \param state State of the item
+         * \param note Note
+         * \param expanded Expanded/collapsed state of the item
+         *
+         * If note is null, creates a new note
+         */
+        NoteItem(const std::string &content="", State state=sNone, bool expanded=false, Note *note=0);
+        /*!
+         * \brief Destructor
+         */
+        ~NoteItem();
+        // accessors
+        /*!
+         * \brief Getter for the type of the item
+         * \return tNote
+         */
+        inline Type type() const override;
+        /*!
+         * \brief Getter for the note
+         * \return Note associated with the item
+         */
+        inline Note* note();
+        // overriden XML-related methods
+        /*!
+         * \brief Loads the item from a XML tree
+         * \param config IO configuration
+         * \param root Position of the item in the XML tree
+         * \param checkFiles Indicates if the existence of potential files is checked (useless here)
+         * \throw xmlpp::exception Thrown when there is an error in the XML tree
+         */
+        void fromXML(const IOConfig &config, const Poco::XML::Element *root, bool checkFiles) override;
+        /*!
+         * \brief Saves the item into a XML tree
+         * \param config IO configuration
+         * \param root Position of the item in the XML tree
+         * \param fileMapping Mapping of files associated with items (useless here)
+         */
+        void toXML(const IOConfig &config, Poco::XML::Element *root, FileMapping &fileMapping) override;
+};
+
+Item::Type NoteItem::type() const
+{
+    return tNote;
+}
+
+Note* NoteItem::note()
+{
+    return pNote;
+}
+
+void NoteItem::setNote(Note *note)
+{
+    pNote = note;
+}
+
+#endif
diff --git a/sources/engine/items/SoundItem.h b/sources/engine/items/SoundItem.h
index 448a19f..8fa7862 100644
--- a/sources/engine/items/SoundItem.h
+++ b/sources/engine/items/SoundItem.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2011-2013 Vincent Prat & Simon Nicolas
+* Copyright © 2011-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -38,9 +38,12 @@ class SoundItem: public FileItem
          * \brief Getter for the type of the item
          * \return Item::tSound
          */
-        Type type() const;
-        // archive subdirectory
-        std::string subdirectory() const;
+        Type type() const override;
+        /*!
+         * \brief Getter for the archive subdirectory corresponding to the item type
+         * \return Sound subdirectory
+         */
+        std::string subdirectory() const override;
 };
 
 inline Item::Type SoundItem::type() const
diff --git a/sources/engine/modifications/CharacterModification.cpp b/sources/engine/modifications/CharacterModification.cpp
index 3ece77e..6d6144a 100644
--- a/sources/engine/modifications/CharacterModification.cpp
+++ b/sources/engine/modifications/CharacterModification.cpp
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2012-2013 Vincent Prat & Simon Nicolas
+* Copyright © 2012-2019 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -20,7 +20,11 @@
 
 using namespace std;
 
-CharacterModification::CharacterModification(CharacterList *list, Character *character, int index, bool isAddition): Modification(isAddition?(Modification::aAddition):(Modification::aDeletion)), etEditType(etCharacter), iIndex(index), pCharacterList(list), pPropertyList(0), pCharacter(character)
+CharacterModification::CharacterModification(CharacterList *list, int index): Modification(Modification::aAddition), etEditType(etCharacter), iIndex(index), pCharacterList(list), pPropertyList(0), pCharacter(0)
+{
+}
+
+CharacterModification::CharacterModification(CharacterList *list, Character *character, int index): Modification(Modification::aDeletion), etEditType(etCharacter), iIndex(index), pCharacterList(list), pPropertyList(0), pCharacter(character)
 {
 }
 
@@ -73,14 +77,16 @@ void CharacterModification::undo()
                             {
                                 switch (action())
                                 {
-                                    case aAddition: pCharacterList->remove(iIndex);
+                                    case aAddition: pCharacter = (*pCharacterList)[iIndex];
+                                                    pCharacterList->remove(iIndex);
                                                     break;
-                                    case aDeletion: pCharacterList->add(*pCharacter, iIndex);
+                                    case aDeletion: pCharacterList->add(pCharacter, iIndex);
+                                                    pCharacter = 0;
                                                     break;
                                     case aEdition:  {
-                                                        Character &character = (*pCharacterList)[iIndex];
-                                                        character.setName(sName);
-                                                        character.setShortDescription(sProperty);
+                                                        Character *character = (*pCharacterList)[iIndex];
+                                                        character->setName(sName);
+                                                        character->setShortDescription(sProperty);
                                                         break;
                                                     }
                                     case aMovement: pCharacterList->move(iNewIndex, iIndex);
@@ -99,7 +105,7 @@ void CharacterModification::undo()
                                             {
                                                 for (CharacterList::iterator it = pCharacterList->begin(); it != pCharacterList->end(); it++)
                                                 {
-                                                    it->removeProperty(iIndex);
+                                                    (*it)->removeProperty(iIndex);
                                                 }
                                             }
                                             break;
@@ -112,7 +118,7 @@ void CharacterModification::undo()
                                                 int i = 0;
                                                 for (CharacterList::iterator it = pCharacterList->begin(); it != pCharacterList->end(); it++)
                                                 {
-                                                    it->addProperty(vValues[i], iIndex);
+                                                    (*it)->addProperty(vValues[i], iIndex);
                                                     i++;
                                                 }
                                             }
@@ -130,7 +136,7 @@ void CharacterModification::undo()
                                             {
                                                 for (CharacterList::iterator it = pCharacterList->begin(); it != pCharacterList->end(); it++)
                                                 {
-                                                    it->moveProperty(iNewIndex, iIndex);
+                                                    (*it)->moveProperty(iNewIndex, iIndex);
                                                 }
                                             }
                                             break;
@@ -139,7 +145,7 @@ void CharacterModification::undo()
                         break;
         case etValue:   if (pCharacterList)
                         {
-                            (*pCharacterList)[iIndex].property(iNewIndex) = sProperty;
+                            (*pCharacterList)[iIndex]->property(iNewIndex) = sProperty;
                         }
                         break;
         default:    break;
@@ -154,14 +160,16 @@ void CharacterModification::redo()
                             {
                                 switch (action())
                                 {
-                                    case aAddition: pCharacterList->add(*pCharacter, iIndex);
+                                    case aAddition: pCharacterList->add(pCharacter, iIndex);
+                                                    pCharacter = 0;
                                                     break;
-                                    case aDeletion: pCharacterList->remove(iIndex);
+                                    case aDeletion: pCharacter = (*pCharacterList)[iIndex];
+                                                    pCharacterList->remove(iIndex);
                                                     break;
                                     case aEdition:  {
-                                                        Character &character = (*pCharacterList)[iIndex];
-                                                        character.setName(sNewName);
-                                                        character.setShortDescription(sNewProperty);
+                                                        Character *character = (*pCharacterList)[iIndex];
+                                                        character->setName(sNewName);
+                                                        character->setShortDescription(sNewProperty);
                                                         break;
                                                     }
                                     case aMovement: pCharacterList->move(iIndex, iNewIndex);
@@ -180,7 +188,7 @@ void CharacterModification::redo()
                                             {
                                                 for (CharacterList::iterator it = pCharacterList->begin(); it != pCharacterList->end(); it++)
                                                 {
-                                                    it->addProperty("0", iIndex);
+                                                    (*it)->addProperty("0", iIndex);
                                                 }
                                             }
                                             break;
@@ -192,7 +200,7 @@ void CharacterModification::redo()
                                             {
                                                 for (CharacterList::iterator it = pCharacterList->begin(); it != pCharacterList->end(); it++)
                                                 {
-                                                    it->removeProperty(iIndex);
+                                                    (*it)->removeProperty(iIndex);
                                                 }
                                             }
                                             break;
@@ -209,7 +217,7 @@ void CharacterModification::redo()
                                             {
                                                 for (CharacterList::iterator it = pCharacterList->begin(); it != pCharacterList->end(); it++)
                                                 {
-                                                    it->moveProperty(iIndex, iNewIndex);
+                                                    (*it)->moveProperty(iIndex, iNewIndex);
                                                 }
                                             }
                                             break;
@@ -218,24 +226,9 @@ void CharacterModification::redo()
                         break;
         case etValue:   if (pCharacterList)
                         {
-                            (*pCharacterList)[iIndex].property(iNewIndex) = sNewProperty;
+                            (*pCharacterList)[iIndex]->property(iNewIndex) = sNewProperty;
                         }
                         break;
         default:    break;
     }
 }
-
-int CharacterModification::index() const
-{
-    return iIndex;
-}
-
-int CharacterModification::newIndex() const
-{
-    return iNewIndex;
-}
-
-CharacterModification::EditionType CharacterModification::editionType() const
-{
-    return etEditType;
-}
diff --git a/sources/engine/modifications/CharacterModification.h b/sources/engine/modifications/CharacterModification.h
index f94ccb4..4d734ed 100644
--- a/sources/engine/modifications/CharacterModification.h
+++ b/sources/engine/modifications/CharacterModification.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2012-2014 Vincent Prat & Simon Nicolas
+* Copyright © 2012-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -42,13 +42,18 @@ class CharacterModification: public Modification
             etValue
         };
         /*!
-         * \brief Constructor for additions/deletions of characters
+         * \brief Constructor for additions of characters
          * \param list List of characters
-         * \param character Character added or deleted
          * \param index Index of the character
-         * \param isAddition Indicates if the modification is an addition (true) or a deletion (false)
          */
-        CharacterModification(CharacterList *list, Character *character, int index, bool isAddition);
+        CharacterModification(CharacterList *list, int index);
+        /*!
+         * \brief Constructor for deletions of characters
+         * \param list List of characters
+         * \param character Deleted character
+         * \param index Index of the character
+         */
+        CharacterModification(CharacterList *list, Character *character, int index);
         /*!
          * \brief Constructor for additions of properties
          * \param list List of properties
@@ -112,26 +117,35 @@ class CharacterModification: public Modification
          * \brief Destructor
          */
         virtual ~CharacterModification();
-        // inherited pure virtual getter
-        Type type() const;
-        // inherited pure virtual methods
-        void undo();
-        void redo();
+        /*!
+         * \brief Getter for the type
+         * \return tCharacter
+         */
+        Type type() const override;
+        //! Undo the modification
+        void undo() override;
+        //! Redo the modification
+        void redo() override;
         /*!
          * \brief Getter for the index
          * \return The index (or the row for cell editions) of the modification
          */
-        int index() const;
+        inline int index() const;
         /*!
          * \brief Getter for the new index
          * \return The new index (or the column for cell editions) of the modification
          */
-        int newIndex() const;
+        inline int newIndex() const;
         /*!
          * \brief Getter for the edition type
          * \return The edition type of the modification
          */
-        EditionType editionType() const;
+        inline EditionType editionType() const;
+        /*!
+         * \brief Getter for the character
+         * \return The added/deleted character
+         */
+        inline Character *character() const;
     private:
         //! Type of edition
         EditionType etEditType;
@@ -157,4 +171,24 @@ class CharacterModification: public Modification
         std::vector<std::string> vValues;
 };
 
+int CharacterModification::index() const
+{
+    return iIndex;
+}
+
+int CharacterModification::newIndex() const
+{
+    return iNewIndex;
+}
+
+CharacterModification::EditionType CharacterModification::editionType() const
+{
+    return etEditType;
+}
+
+Character* CharacterModification::character() const
+{
+    return pCharacter;
+}
+
 #endif
diff --git a/sources/engine/modifications/MetadataModification.h b/sources/engine/modifications/MetadataModification.h
index a8eb73a..57230b0 100644
--- a/sources/engine/modifications/MetadataModification.h
+++ b/sources/engine/modifications/MetadataModification.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2013 Vincent Prat & Simon Nicolas
+* Copyright © 2013-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -36,9 +36,15 @@ class MetadataModification: public Modification
          */
         MetadataModification(Metadata &metadata, const Metadata &newMetadata, const Metadata &oldMetadata);
         // inherited pure virtual methods
-        Type type() const;
-        void undo();
-        void redo();
+        /*!
+         * \brief Getter for the type
+         * \return tMetadata
+         */
+        Type type() const override;
+        //! Undo the modification
+        void undo() override;
+        //! Redo the modification
+        void redo() override;
     private:
         //! Modified metadata
         Metadata &mMetadata;
diff --git a/sources/engine/modifications/NoteModification.cpp b/sources/engine/modifications/NoteModification.cpp
index a34b851..170e894 100644
--- a/sources/engine/modifications/NoteModification.cpp
+++ b/sources/engine/modifications/NoteModification.cpp
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2012-2013 Vincent Prat & Simon Nicolas
+* Copyright © 2012-2019 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -20,46 +20,53 @@
 
 using namespace std;
 
-NoteModification::NoteModification(string &note, const string &content, const string &newContent, int index): Modification(aEdition), rNote(note), sContent(content), sNewContent(newContent), iIndex(index)
+NoteModification::NoteModification(Note &note, const string &content, const string &newContent, int index): Modification(aEdition), rNote(note), sContent(content), sNewContent(newContent), iIndex(index), etEditType(etText)
 {
 }
 
-NoteModification::NoteModification(string &note, int index, int newIndex, int length): Modification(aMovement), rNote(note), iIndex(index), iNewIndex(newIndex), iLength(length)
+NoteModification::NoteModification(Note &note, int index, int newIndex, int length): Modification(aMovement), rNote(note), iIndex(index), iNewIndex(newIndex), iLength(length)
 {
 }
 
-NoteModification::NoteModification(string &note, Action action, const string &content, int index): Modification(action), rNote(note), sContent(content), iIndex(index)
+NoteModification::NoteModification(Note &note, Action action, const string &content, int index): Modification(action), rNote(note), sContent(content), iIndex(index)
 {
 }
 
-NoteModification::~NoteModification()
+NoteModification::NoteModification(Note &note, const string &title, const string &newTitle): Modification(aEdition), rNote(note), sContent(title), sNewContent(newTitle), etEditType(etTitle)
 {
 }
 
-Modification::Type NoteModification::type() const
+NoteModification::~NoteModification()
 {
-    return tNote;
 }
 
 void NoteModification::undo()
 {
     int l = sContent.size();
+    string text = rNote.text();
     switch (action())
     {
         case aMovement: if (iIndex < iNewIndex)
                         {
-                            rNote = rNote.substr(0, iIndex) + rNote.substr(iNewIndex - iLength, iLength) + rNote.substr(iIndex, iNewIndex - iIndex - iLength) + rNote.substr(iNewIndex);
+                            rNote.text() = text.substr(0, iIndex) + text.substr(iNewIndex - iLength, iLength) + text.substr(iIndex, iNewIndex - iIndex - iLength) + text.substr(iNewIndex);
                         }
                         else
                         {
-                            rNote = rNote.substr(0, iNewIndex) + rNote.substr(iNewIndex + iLength, iIndex - iNewIndex) + rNote.substr(iNewIndex, iLength) + rNote.substr(iIndex + iLength);
+                            rNote.text() = text.substr(0, iNewIndex) + text.substr(iNewIndex + iLength, iIndex - iNewIndex) + text.substr(iNewIndex, iLength) + text.substr(iIndex + iLength);
                         }
                         break;
-        case aEdition:  rNote = rNote.substr(0, iIndex) + sContent + rNote.substr(iIndex + sNewContent.size());
+        case aEdition:  if (etEditType == etText)
+                        {
+                            rNote.text() = text.substr(0, iIndex) + sContent + text.substr(iIndex + sNewContent.size());
+                        }
+                        else
+                        {
+                            rNote.setTitle(sContent);
+                        }
                         break;
-        case aAddition: rNote = rNote.substr(0, iIndex) + rNote.substr(iIndex + l);
+        case aAddition: rNote.text() = text.substr(0, iIndex) + text.substr(iIndex + l);
                         break;
-        case aDeletion: rNote = rNote.substr(0, iIndex) + sContent + rNote.substr(iIndex);
+        case aDeletion: rNote.text() = text.substr(0, iIndex) + sContent + text.substr(iIndex);
                         break;
     }
 }
@@ -67,47 +74,30 @@ void NoteModification::undo()
 void NoteModification::redo()
 {
     int l = sContent.size();
+    string text = rNote.text();
     switch (action())
     {
         case aMovement: if (iIndex < iNewIndex)
                         {
-                            rNote = rNote.substr(0, iIndex) + rNote.substr(iIndex + iLength, iNewIndex - iIndex - iLength) + rNote.substr(iIndex, iLength) + rNote.substr(iNewIndex);
+                            rNote.text() = text.substr(0, iIndex) + text.substr(iIndex + iLength, iNewIndex - iIndex - iLength) + text.substr(iIndex, iLength) + text.substr(iNewIndex);
                         }
                         else
                         {
-                            rNote = rNote.substr(0, iNewIndex) + rNote.substr(iIndex, iLength) + rNote.substr(iNewIndex, iIndex - iNewIndex) + rNote.substr(iIndex + iLength);
+                            rNote.text() = text.substr(0, iNewIndex) + text.substr(iIndex, iLength) + text.substr(iNewIndex, iIndex - iNewIndex) + text.substr(iIndex + iLength);
                         }
                         break;
-        case aEdition:  rNote = rNote.substr(0, iIndex) + sNewContent + rNote.substr(iIndex + l);
+        case aEdition:  if (etEditType == etText)
+                        {
+                            rNote.text() = text.substr(0, iIndex) + sNewContent + text.substr(iIndex + l);
+                        }
+                        else
+                        {
+                            rNote.setTitle(sNewContent);
+                        }
                         break;
-        case aAddition: rNote = rNote.substr(0, iIndex) + sContent + rNote.substr(iIndex);
+        case aAddition: rNote.text() = text.substr(0, iIndex) + sContent + text.substr(iIndex);
                         break;
-        case aDeletion: rNote = rNote.substr(0, iIndex) + rNote.substr(iIndex + l);
+        case aDeletion: rNote.text() = text.substr(0, iIndex) + text.substr(iIndex + l);
                         break;
     }
 }
-
-int NoteModification::index() const
-{
-    return iIndex;
-}
-
-int NoteModification::newIndex() const
-{
-    return iNewIndex;
-}
-
-int NoteModification::length() const
-{
-    return iLength;
-}
-
-string NoteModification::content() const
-{
-    return sContent;
-}
-
-string NoteModification::newContent() const
-{
-    return sNewContent;
-}
diff --git a/sources/engine/modifications/NoteModification.h b/sources/engine/modifications/NoteModification.h
index 7213d5f..00fe444 100644
--- a/sources/engine/modifications/NoteModification.h
+++ b/sources/engine/modifications/NoteModification.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2012-2013 Vincent Prat & Simon Nicolas
+* Copyright © 2012-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -21,6 +21,7 @@
 
 #include "Modification.h"
 #include <string>
+#include "Note.h"
 
 /*!
  * \brief Modification of the notes
@@ -28,6 +29,12 @@
 class NoteModification: public Modification
 {
     public:
+        //! Edition type
+        enum EditionType
+        {
+            etTitle,
+            etText
+        };
         /*!
          * \brief Constructor for replacements
          * \param note Modified note
@@ -35,7 +42,7 @@ class NoteModification: public Modification
          * \param newContent Modified content
          * \param index Index of the modification
          */
-        NoteModification(std::string &note, const std::string &content, const std::string &newContent, int index);
+        NoteModification(Note &note, const std::string &content, const std::string &newContent, int index);
         /*!
          * \brief Constructor for moves
          * \param note Modified note
@@ -43,7 +50,7 @@ class NoteModification: public Modification
          * \param newIndex New index of the moved text
          * \param length Length of the moved text
          */
-        NoteModification(std::string &note, int index, int newIndex, int length);
+        NoteModification(Note &note, int index, int newIndex, int length);
         /*!
          * \brief Constructor for additions and deletions
          * \param note Modified note
@@ -51,43 +58,66 @@ class NoteModification: public Modification
          * \param content Added or deleted text
          * \param index Index of the modification
          */
-        NoteModification(std::string &note, Action action, const std::string &content, int index);
+        NoteModification(Note &note, Action action, const std::string &content, int index);
+        /*!
+         * \brief Constructor for renaming
+         * \param note Modified note
+         * \param title Previous title
+         * \param newTitle Modified title
+         */
+        NoteModification(Note &note, const std::string &title, const std::string &newTitle);
         /*!
          * \brief Destructor
          */
         virtual ~NoteModification();
         // inherited pure virtual methods
-        Type type() const;
-        void undo();
-        void redo();
+        /*!
+         * \brief Getter for the type
+         * \return tNote
+         */
+        inline Type type() const override;
+        //! Undo the modification
+        void undo() override;
+        //! Redo the modification
+        void redo() override;
         /*!
          * \brief Getter for the index
          * \return Index of the modification
          */
-        int index() const;
+        inline int index() const;
         /*!
          * \brief Getter for the new index
          * \return New index of the modification
          */
-        int newIndex() const;
+        inline int newIndex() const;
         /*!
          * \brief Getter for the length
          * \return Length of the moved text
          */
-        int length() const;
+        inline int length() const;
         /*!
          * \brief Getter for the modified content
          * \return Modified text
          */
-        std::string content() const;
+        inline std::string content() const;
         /*!
          * \brief Getter for the new content
          * \return New text
          */
-        std::string newContent() const;
+        inline std::string newContent() const;
+        /*!
+         * \brief Getter for the note
+         *  \return Note
+         */
+        inline Note& note();
+        /*!
+         * \brief Getter for the edition type
+         * \return Edition type
+         */
+        inline EditionType editionType() const;
     private:
         //! Modified note
-        std::string &rNote;
+        Note &rNote;
         //! Previous content
         std::string sContent;
         //! Modified content
@@ -98,6 +128,48 @@ class NoteModification: public Modification
         int iNewIndex;
         //! Length of the moved text
         int iLength;
+        //! Edition type
+        EditionType etEditType;
 };
 
+Modification::Type NoteModification::type() const
+{
+    return tNote;
+}
+
+int NoteModification::index() const
+{
+    return iIndex;
+}
+
+int NoteModification::newIndex() const
+{
+    return iNewIndex;
+}
+
+int NoteModification::length() const
+{
+    return iLength;
+}
+
+std::string NoteModification::content() const
+{
+    return sContent;
+}
+
+std::string NoteModification::newContent() const
+{
+    return sNewContent;
+}
+
+Note& NoteModification::note()
+{
+    return rNote;
+}
+
+NoteModification::EditionType NoteModification::editionType() const
+{
+    return etEditType;
+}
+
 #endif
diff --git a/sources/engine/modifications/TreeModification.cpp b/sources/engine/modifications/TreeModification.cpp
index 7d741a5..d5732e1 100644
--- a/sources/engine/modifications/TreeModification.cpp
+++ b/sources/engine/modifications/TreeModification.cpp
@@ -22,27 +22,28 @@
 
 using namespace std;
 
-TreeModification::TreeModification(Tree &tree, Item *newItem, const string &indices): Modification(aAddition), sIndices(indices), rTree(tree), pBranch(0), pItem(0), pNewItem(newItem), pUndoneItem(0)
+TreeModification::TreeModification(Tree &tree, const string &indices): Modification(aAddition), sIndices(indices), rTree(tree), pBranch(0), pItem(0), pUndoneItem(0), pCurrentItem(0)
 {
 }
 
-TreeModification::TreeModification(Tree &tree, Branch *branch, const string &indices): Modification(aDeletion), sIndices(indices), rTree(tree), pBranch(branch), pItem(0), pNewItem(0), pUndoneItem(0)
+TreeModification::TreeModification(Tree &tree, Branch *branch, const string &indices): Modification(aDeletion), sIndices(indices), rTree(tree), pBranch(branch), pItem(0), pUndoneItem(0), pCurrentItem(0)
 {
 }
 
-TreeModification::TreeModification(Tree &tree, Item *item, Item *newItem, const string &indices): Modification(aEdition), etEditType(etFull), sIndices(indices), rTree(tree), pBranch(0), pItem(item), pNewItem(newItem), pUndoneItem(0)
+TreeModification::TreeModification(Tree &tree, Item *oldItem, const string &indices): Modification(aEdition), etEditType(etFull), sIndices(indices), rTree(tree), pBranch(0), pItem(oldItem), pUndoneItem(0), pCurrentItem(0)
 {
+    bSameType = (oldItem->type() == rTree[indices]->type());
 }
 
-TreeModification::TreeModification(Tree &tree, const string &content, const string &newContent, const string &indices): Modification(aEdition), etEditType(etContent), sIndices(indices), rTree(tree), pBranch(0), pItem(0), pNewItem(0), sContent(content), sNewContent(newContent), pUndoneItem(0)
+TreeModification::TreeModification(Tree &tree, const string &content, const string &newContent, const string &indices): Modification(aEdition), etEditType(etContent), sIndices(indices), rTree(tree), pBranch(0), pItem(0), sContent(content), sNewContent(newContent), pUndoneItem(0), pCurrentItem(0)
 {
 }
 
-TreeModification::TreeModification(Tree &tree, Item::State state, Item::State newState, const string &indices): Modification(aEdition), etEditType(etState), sIndices(indices), rTree(tree), pBranch(0), pItem(0), pNewItem(0), sState(state), sNewState(newState), pUndoneItem(0)
+TreeModification::TreeModification(Tree &tree, Item::State state, Item::State newState, const string &indices): Modification(aEdition), etEditType(etState), sIndices(indices), rTree(tree), pBranch(0), pItem(0), sState(state), sNewState(newState), pUndoneItem(0), pCurrentItem(0)
 {
 }
 
-TreeModification::TreeModification(Tree &tree, const string &indices, const string &newIndices): Modification(aMovement), sIndices(indices), sNewIndices(newIndices), rTree(tree), pBranch(0), pItem(0), pNewItem(0), pUndoneItem(0)
+TreeModification::TreeModification(Tree &tree, const string &indices, const string &newIndices): Modification(aMovement), sIndices(indices), sNewIndices(newIndices), rTree(tree), pBranch(0), pItem(0), pUndoneItem(0), pCurrentItem(0)
 {
 }
 
@@ -54,14 +55,20 @@ TreeModification::~TreeModification()
     }
     if (pItem)
     {
+        // to avoid double free of notes
+        if (pItem->type() == Item::tNote && bSameType)
+        {
+            static_cast<NoteItem*>(pItem)->setNote(0);
+        }
         delete pItem;
     }
-    if (pNewItem)
-    {
-        delete pNewItem;
-    }
     if (pUndoneItem)
     {
+        // to avoid double free of notes
+        if (pUndoneItem->type() == Item::tNote && bSameType)
+        {
+            static_cast<NoteItem*>(pUndoneItem)->setNote(0);
+        }
         delete pUndoneItem;
     }
 }
@@ -79,8 +86,9 @@ void TreeModification::undo()
         case aEdition:  switch (etEditType)
                         {
                             case etFull:    pUndoneItem = rTree[sIndices];
-                                            pCurrentItem = ItemFactory::copyItem(pItem);
-                                            rTree.setItem(sIndices, pCurrentItem);
+                                            rTree.setItem(sIndices, pItem);
+                                            pCurrentItem = pItem;
+                                            pItem = 0;
                                             break;
                             case etContent: rTree[sIndices]->setContent(sContent);
                                             break;
@@ -98,16 +106,18 @@ void TreeModification::redo()
 {
     switch (action())
     {
-        case aAddition: rTree.insert(sIndices, new Branch(ItemFactory::copyItem(pNewItem)));
+        case aAddition: rTree.insert(sIndices, new Branch(pUndoneItem));
+                        pUndoneItem = 0;
                         break;
         case aDeletion: pBranch = rTree.branch(sIndices);
                         rTree.remove(sIndices, false);
                         break;
         case aEdition:  switch (etEditType)
                         {
-                            case etFull:    pUndoneItem = rTree[sIndices];
-                                            pCurrentItem = ItemFactory::copyItem(pNewItem);
-                                            rTree.setItem(sIndices, pCurrentItem);
+                            case etFull:    pItem = rTree[sIndices];
+                                            rTree.setItem(sIndices, pUndoneItem);
+                                            pCurrentItem = pUndoneItem;
+                                            pUndoneItem = 0;
                                             break;
                             case etContent: rTree[sIndices]->setContent(sNewContent);
                                             break;
@@ -222,12 +232,3 @@ string TreeModification::deletedIndices() const
         return buf.str();
     }
 }
-
-void TreeModification::freeUndoneItem()
-{
-    if (pUndoneItem)
-    {
-        delete pUndoneItem;
-        pUndoneItem = 0;
-    }
-}
diff --git a/sources/engine/modifications/TreeModification.h b/sources/engine/modifications/TreeModification.h
index 00643f9..507818c 100644
--- a/sources/engine/modifications/TreeModification.h
+++ b/sources/engine/modifications/TreeModification.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2012-2014 Vincent Prat & Simon Nicolas
+* Copyright © 2012-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -43,25 +43,23 @@ class TreeModification: public Modification
         /*!
          * \brief Constructor for additions
          * \param tree Modified tree
-         * \param newItem Copy of the new item
-         * \param indices Indices of the item
+         * \param indices Indices of the new item
          */
-        TreeModification(Tree &tree, Item *newItem, const std::string &indices);
+        TreeModification(Tree &tree, const std::string &indices);
         /*!
          * \brief Constructor for deletions
          * \param tree Modified tree
-         * \param branch Copy of the deleted branch
+         * \param branch Deleted branch
          * \param indices Indices of the branch
          */
         TreeModification(Tree &tree, Branch *branch, const std::string &indices);
         /*!
          * \brief Constructor for full editions
          * \param tree Modified tree
-         * \param item Copy of the previous item
-         * \param newItem Copy of the new item
+         * \param oldItem Previous item
          * \param indices Indices of the item
          */
-        TreeModification(Tree &tree, Item *item, Item *newItem, const std::string &indices);
+        TreeModification(Tree &tree, Item *oldItem, const std::string &indices);
         /*!
          * \brief Constructor for content-only editions
          * \param tree Modified tree
@@ -89,16 +87,21 @@ class TreeModification: public Modification
          * \brief Destructor
          */
         virtual ~TreeModification();
-        // inherited pure virtual getter
-        inline Type type() const;
+        /*!
+         * \brief Getter for the type
+         * \return tTree
+         */
+        inline Type type() const override;
         /*!
          * \brief Getter for the tree
          * \return Modified tree
          */
         inline Tree& tree();
         // inherited pure virtual methods
-        void undo();
-        void redo();
+        //! Undo the modification
+        void undo() override;
+        //! Redo the modification
+        void redo() override;
         /*!
          * \brief Getter for the indices
          * \return Indices of the modification
@@ -120,19 +123,10 @@ class TreeModification: public Modification
          */
         std::string deletedIndices() const;
         /*!
-         * \brief Getter for the modified item (or the previous when undoing an addition)
-         * \return Modified item or just undone added item (to be deleted separately by freeItem))
+         * \brief Getter for the old version of a newly edited item
+         * \return Old item
          */
         inline Item* item() const;
-        /*!
-         * \brief Getter for the newly added item
-         * \return New item
-         */
-        inline Item* newItem() const;
-        /*!
-         * \brief Deletion of the undone item
-         */
-        void freeUndoneItem();
         /*!
          * \brief Getter for the deleted branch
          * \return Deleted branch
@@ -168,8 +162,6 @@ class TreeModification: public Modification
         Branch *pBranch;
         //! Copy of the modified item
         Item *pItem;
-        //! Copy of the new item
-        Item *pNewItem;
         //! Previous content
         std::string sContent;
         //! New content
@@ -182,6 +174,8 @@ class TreeModification: public Modification
         Item *pUndoneItem;
         //! Current copy of the item (for editions)
         Item *pCurrentItem; 
+        //! Flag to indicate if a full edition conserves the item type
+        bool bSameType;
 };
 
 Modification::Type TreeModification::type() const
@@ -204,11 +198,6 @@ Item* TreeModification::item() const
     return pItem;
 }
 
-Item* TreeModification::newItem() const
-{
-    return pNewItem;
-}
-
 Branch* TreeModification::branch() const
 {
     return pBranch;
diff --git a/sources/widgets/QCustomHeaderView.cpp b/sources/widgets/QCustomHeaderView.cpp
index b0f55ae..5f04c44 100644
--- a/sources/widgets/QCustomHeaderView.cpp
+++ b/sources/widgets/QCustomHeaderView.cpp
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2011-2017 Vincent Prat & Simon Nicolas
+* Copyright © 2011-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -33,3 +33,14 @@ void QCustomHeaderView::mousePressEvent(QMouseEvent *e)
     emit clicked(logicalIndexAt(e->pos()), e->button(), e->globalPos());
     QHeaderView::mousePressEvent(e);
 }
+
+bool QCustomHeaderView::event(QEvent *e)
+{
+    if (e->type() == QEvent::ToolTip)
+    {
+        QHelpEvent *helpEvent = static_cast<QHelpEvent*>(e);
+        emit toolTipRequested(visualIndex(logicalIndexAt(helpEvent->pos())), helpEvent->globalPos());
+        return true;
+    }
+    return QHeaderView::event(e);
+}
diff --git a/sources/widgets/QCustomHeaderView.h b/sources/widgets/QCustomHeaderView.h
index 69b3110..d3add9c 100644
--- a/sources/widgets/QCustomHeaderView.h
+++ b/sources/widgets/QCustomHeaderView.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2011-2017 Vincent Prat & Simon Nicolas
+* Copyright © 2011-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -34,7 +34,14 @@ class QCustomHeaderView: public QHeaderView
          *
          * Detect right clicks and send the rightClicked signal
          */
-        void mousePressEvent(QMouseEvent *e);
+        void mousePressEvent(QMouseEvent *e) override;
+        /*!
+         * \brief Event handler
+         * \param e Event
+         *
+         * This handler is used to display dynamical tool tips.
+         */
+        bool event(QEvent *e) override;
 
     public:
         /*!
@@ -52,6 +59,12 @@ class QCustomHeaderView: public QHeaderView
          * \param position Global position of the click (used for showing a popup menu)
          */
         void clicked(int index, Qt::MouseButton button, const QPoint &position);
+        /*!
+         * \brief Signal emitted when a tool tip should be displayed
+         * \param index Visual index of the tool tip
+         * \param position Global position of the tool tip
+         */
+        void toolTipRequested(int index, const QPoint &position);
 };
 
 #endif
diff --git a/sources/widgets/QCustomTabBar.cpp b/sources/widgets/QCustomTabBar.cpp
new file mode 100644
index 0000000..715363d
--- /dev/null
+++ b/sources/widgets/QCustomTabBar.cpp
@@ -0,0 +1,43 @@
+/*************************************************************************
+* Copyright © 2019-2020 Vincent Prat & Simon Nicolas
+*
+* 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, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*************************************************************************/
+
+#include "QCustomTabBar.h"
+
+QCustomTabBar::QCustomTabBar(QWidget *parent): QTabBar(parent)
+{
+}
+
+void QCustomTabBar::mousePressEvent(QMouseEvent *e)
+{
+    if (e->button()==Qt::RightButton)
+    {
+        emit rightClicked(tabAt(e->pos()), e->globalPos());
+    }
+    QTabBar::mousePressEvent(e);
+}
+
+bool QCustomTabBar::event(QEvent *e)
+{
+    if (e->type() == QEvent::ToolTip)
+    {
+        QHelpEvent *helpEvent = static_cast<QHelpEvent*>(e);
+        emit toolTipRequested(tabAt(helpEvent->pos()), helpEvent->globalPos());
+        return true;
+    }
+    return QTabBar::event(e);
+}
diff --git a/sources/widgets/QCustomTabBar.h b/sources/widgets/QCustomTabBar.h
new file mode 100644
index 0000000..e2fe8d2
--- /dev/null
+++ b/sources/widgets/QCustomTabBar.h
@@ -0,0 +1,68 @@
+/*************************************************************************
+* Copyright © 2019-2020 Vincent Prat & Simon Nicolas
+*
+* 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, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*************************************************************************/
+
+#ifndef HEADER_QCUSTOMTABBAR
+#define HEADER_QCUSTOMTABBAR
+
+#include <QTabBar>
+#include <QMouseEvent>
+
+//! Bar for the custom tab widget
+class QCustomTabBar: public QTabBar
+{
+    Q_OBJECT
+
+    protected:
+        /*!
+         * \brief MousePress event handler
+         * \param e Event to handle
+         *
+         * Detect right clicks and send the rightClicked signal
+         */
+        void mousePressEvent(QMouseEvent *e) override;
+        /*!
+         * \brief Event handler
+         * \param e Event
+         *
+         * This handler is used to display dynamical tool tips.
+         */
+        bool event(QEvent *e) override;
+
+    public:
+        /*!
+         * \brief Constructor
+         * \param parent Parent widget
+         */
+        QCustomTabBar(QWidget *parent=0);
+
+    signals:
+        /*!
+         * \brief Signal emitted when the bar is right-clicked
+         * \param index Index of the clicked tab
+         * \param position Global position of the click (used for showing a popup menu)
+         */
+        void rightClicked(int index, const QPoint &position);
+        /*!
+         * \brief Signal emitted when a tool tip should be displayed
+         * \param index Index of the tab
+         * \param position Global position of the tool tip
+         */
+        void toolTipRequested(int index, const QPoint &position);
+};
+
+#endif
diff --git a/sources/widgets/QCustomTabWidget.cpp b/sources/widgets/QCustomTabWidget.cpp
new file mode 100644
index 0000000..a966885
--- /dev/null
+++ b/sources/widgets/QCustomTabWidget.cpp
@@ -0,0 +1,179 @@
+/*************************************************************************
+* Copyright © 2016-2020 Vincent Prat & Simon Nicolas
+*
+* 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, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*************************************************************************/
+
+#include "QCustomTabWidget.h"
+#include "QCustomTabBar.h"
+#include <QToolTip>
+#include <QApplication>
+
+using namespace std;
+
+QCustomTabWidget::QCustomTabWidget(QWidget *parent): QTabWidget(parent), pFilter(0), pMenu(new QMenu(this)), pRenameDialog(new RenameNoteDialog(this))
+{
+    // popup menu
+    actionRename = new QAction(this);
+    actionRename->setIcon(QIcon(":/data/images/pencil.svg"));
+    actionClose = new QAction(this);
+    actionClose->setIcon(QIcon(":/data/images/remove.svg"));
+    pMenu->addAction(actionRename);
+    pMenu->addAction(actionClose);
+
+    // tab bar
+    QTabBar *bar = new QCustomTabBar(this);
+    setTabBar(bar);
+
+    // self-connection
+    connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(onTabCloseRequested(int)));
+    // connections with the bar
+    connect(bar, SIGNAL(rightClicked(int, const QPoint&)), this, SLOT(onRightClicked(int, const QPoint&)));
+    connect(bar, SIGNAL(toolTipRequested(int, const QPoint&)), this, SLOT(onToolTipRequested(int, const QPoint&)));
+
+    // text of the menu
+    retranslate();
+}
+
+void QCustomTabWidget::clear()
+{
+    for (int i = 0; i < count(); i++)
+    {
+        delete widget(i);
+    }
+    QTabWidget::clear();
+    mNotes.clear();
+}
+
+bool QCustomTabWidget::unregisteredModification() const
+{
+    return static_cast<QCustomTextEdit*>(currentWidget())->unregisteredModification();
+}
+
+void QCustomTabWidget::updateModification(NoteModification *modification, bool undo)
+{
+    Note *note = &modification->note();
+    QCustomTextEdit *textEdit = openNote(note);
+    if (modification->action() == Modification::aEdition && modification->editionType() == NoteModification::etTitle)
+    {
+        int index = indexOf(textEdit);
+        setTabText(index, note->title().c_str());
+    }
+    else
+    {
+        textEdit->updateModification(modification, undo);
+    }
+}
+
+void QCustomTabWidget::installEventFilter(QObject *filter)
+{
+    pFilter = filter;
+}
+
+QCustomTextEdit* QCustomTabWidget::openNote(Note *note)
+{
+    QCustomTextEdit *textEdit;
+    map<Note*, QCustomTextEdit*>::const_iterator it = mNotes.find(note);
+    if (it == mNotes.end())
+    {
+        // create a new TextEdit widget and add it to the tab
+        textEdit = new QCustomTextEdit(this, pFilter);
+        textEdit->setNote(note);
+        addTab(textEdit, note->title().c_str());
+        note->setVisible(true);
+        mNotes.insert(pair<Note*, QCustomTextEdit*>(note, textEdit));
+        emit noteOpened(textEdit);
+    }
+    else
+    {
+        textEdit = it->second;
+        if(!note->visible())
+        {
+            // reopen the note if previously closed
+            addTab(it->second, note->title().c_str());
+            note->setVisible(true);
+        }
+    }
+    setCurrentWidget(textEdit);
+    return textEdit;
+}
+
+void QCustomTabWidget::onTabCloseRequested(int index)
+{
+    if (index > 0)
+    {
+        note(index)->setVisible(false);
+        removeTab(index);
+    }
+}
+
+void QCustomTabWidget::deleteNote(Note *note)
+{
+    map<Note*, QCustomTextEdit*>::const_iterator it = mNotes.find(note);
+    if (it != mNotes.end())
+    {
+        delete (*it).second;
+        mNotes.erase(it);
+    }
+}
+
+void QCustomTabWidget::onRightClicked(int index, const QPoint& position)
+{
+    // the main tab cannot be renamed or closed
+    if (index > 0)
+    {
+        setCurrentIndex(index);
+        QAction *action = pMenu->exec(position);
+        if (action == actionRename)
+        {
+            renameNote(index);
+        }
+        else if (action == actionClose)
+        {
+            onTabCloseRequested(index);
+        }
+    }
+}
+
+void QCustomTabWidget::onToolTipRequested(int index, const QPoint& position)
+{
+    QToolTip::showText(position, tabText(index));
+}
+
+void QCustomTabWidget::retranslate()
+{
+    actionRename->setText(QApplication::translate("customTab", "&Rename", 0));
+    actionRename->setStatusTip(QApplication::translate("customTab", "Rename the note", 0));
+    actionRename->setShortcut(QString("Ctrl+F2"));
+    actionClose->setText(QApplication::translate("customTab", "&Close", 0));
+    actionClose->setStatusTip(QApplication::translate("customTab", "Close the note", 0));
+    actionClose->setShortcut(QString("Ctrl+Del"));
+}
+
+void QCustomTabWidget::renameNote(int index)
+{
+    if (index > 0)
+    {
+        if (pRenameDialog->exec(tabText(index)) == QDialog::Accepted)
+        {
+            QString qNewTitle = pRenameDialog->text();
+            setTabText(index, qNewTitle);
+            std::string newTitle = qNewTitle.toStdString();
+            Note *pNote = note(index);
+            emit modificationDone(new NoteModification(*pNote, pNote->title(), newTitle));
+            pNote->setTitle(newTitle);
+        }
+    }
+}
diff --git a/sources/widgets/QCustomTabWidget.h b/sources/widgets/QCustomTabWidget.h
new file mode 100644
index 0000000..8a3b3d7
--- /dev/null
+++ b/sources/widgets/QCustomTabWidget.h
@@ -0,0 +1,140 @@
+/*************************************************************************
+* Copyright © 2016-2020 Vincent Prat & Simon Nicolas
+*
+* 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, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*************************************************************************/
+
+#ifndef HEADER_QCUSTOMTABWIDGET
+#define HEADER_QCUSTOMTABWIDGET
+
+#include <QTabWidget>
+#include "QCustomTextEdit.h"
+#include "Note.h"
+#include <QAction>
+#include <QMenu>
+#include "RenameNoteDialog.h"
+
+/*!
+ * \brief Custom tab widget for notes
+ */
+class QCustomTabWidget: public QTabWidget
+{
+    Q_OBJECT
+
+    public:
+        /*!
+         * \brief Constructor
+         * \param parent Parent widget
+         */
+        QCustomTabWidget(QWidget *parent=0);
+        /*!
+         * \brief Indicator of unregistered modifications
+         * \return True if there is an unregistered modification
+         */
+        bool unregisteredModification() const;
+        /*!
+         * \brief Overriden method for installing event filter
+         * \param filter Filter
+         *
+         * This method stores the filter instead of actually using it, and installs it for all subwidgets
+         */
+        void installEventFilter(QObject *filter);
+        /*!
+         * \brief Method to rename a note
+         * \param index Index of the tab
+         */
+        void renameNote(int index);
+        /*!
+         * \brief Getter for the note at a given index
+         * \param index Index of the tab
+         * \return Note at the given index
+         */
+        inline Note* note(int index);
+    public slots:
+        /*!
+         * \brief Update after a modification
+         * \param modification Modification to undo or redo
+         * \param undo True to undo, false to redo
+         */
+        void updateModification(NoteModification *modification, bool undo);
+        //! Clear the widget
+        void clear();
+        /*!
+         * \brief Open a note
+         * \param note Note to open
+         * \return TextEdit widget corresponding to the note
+         */
+        QCustomTextEdit* openNote(Note *note);
+        /*!
+         * \brief Slot for when a tab is closing
+         * \param index Index of the tab to close
+         */
+        void onTabCloseRequested(int index);
+        /*!
+         * \brief Delete a note
+         * \param note Note to delete
+         */
+        void deleteNote(Note *note);
+        /*!
+         * \brief Slot for when a tab is right-clicked
+         * \param index Index of the tab
+         * \param position Global position of the click
+         */
+        void onRightClicked(int index, const QPoint& position);
+        /*!
+         * \brief Slot for when a tool tip is requested
+         * \param index Index of the tab
+         * \param position Global position of the tool tip
+         */
+        void onToolTipRequested(int index, const QPoint& position);
+    signals:
+        /*!
+         * \brief Signal emitted when a note is opened
+         * \param note Editor for this note
+         */
+        void noteOpened(QCustomTextEdit *note);
+        /*!
+         * \brief Signal to register a modification
+         * \param modification Modification to register
+         */
+        void modificationDone(Modification *modification);
+    protected:
+         /*!
+         * \brief Retranslator
+         *
+         * Retranslates the menu
+         */
+        void retranslate();
+    private:
+        //! Map of notes and widgets
+        std::map<Note*, QCustomTextEdit*> mNotes;
+        //! Event filter
+        QObject *pFilter;
+        //! Popup menu
+        QMenu *pMenu;
+        //! Action for renaming
+        QAction *actionRename;
+        //! Action for closure
+        QAction *actionClose;
+        //! Dialog window for renaming
+        RenameNoteDialog *pRenameDialog;
+};
+
+Note* QCustomTabWidget::note(int index)
+{
+    return static_cast<QCustomTextEdit*>(widget(index))->note();
+}
+
+#endif
diff --git a/sources/widgets/QCustomTableWidget.cpp b/sources/widgets/QCustomTableWidget.cpp
index a7ade2d..9944734 100644
--- a/sources/widgets/QCustomTableWidget.cpp
+++ b/sources/widgets/QCustomTableWidget.cpp
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2011-2018 Vincent Prat & Simon Nicolas
+* Copyright © 2011-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -17,12 +17,12 @@
 *************************************************************************/
 
 #include "QCustomTableWidget.h"
-#include "QCustomHeaderView.h"
 #include "ChangePropertyDialog.h"
 #include <QApplication>
 #include <QScrollBar>
+#include <QToolTip>
 
-QCustomTableWidget::QCustomTableWidget(QWidget *parent): QTableWidget(parent), menu(new QMenu(this)), hMenu(new QMenu(this)), vMenu(new QMenu(this)), pChangePropertyDial(new ChangePropertyDialog(this)), pChangeCharacterDial(new ChangeCharacterDialog(this)), pProperties(0), pCharacters(0), bEditing(false), bUpdate(false), iCreatedCells(0), eSelected(QAbstractItemView::SelectItems)
+QCustomTableWidget::QCustomTableWidget(QWidget *parent): QTableWidget(parent), menu(new QMenu(this)), hMenu(new QMenu(this)), vMenu(new QMenu(this)), pChangePropertyDial(new ChangePropertyDialog(this)), pChangeCharacterDial(new ChangeCharacterDialog(this)), pProperties(0), pCharacters(0), bEditing(false), bUpdate(false), iCreatedCells(0), pVHeader(new QCustomHeaderView(Qt::Vertical,this)), eSelected(QAbstractItemView::SelectItems)
 {
     // property menu
     actionAddColumn = new QAction(this);
@@ -47,22 +47,26 @@ QCustomTableWidget::QCustomTableWidget(QWidget *parent): QTableWidget(parent), m
     // main menu
     menu->addMenu(hMenu);
     menu->addMenu(vMenu);
-    // sets the text of the menus
-    retranslate();
 
     // headers
-    setHorizontalHeader(new QCustomHeaderView(Qt::Horizontal,this));
-    setVerticalHeader(new QCustomHeaderView(Qt::Vertical,this));
+    setVerticalHeader(pVHeader);
+    QCustomHeaderView *header = new QCustomHeaderView(Qt::Horizontal,this);
+    setHorizontalHeader(header);
 
-    // connection of signals
-    QCustomHeaderView *header = dynamic_cast<QCustomHeaderView*>(horizontalHeader());
+    // connections with the horizontal header
     connect(header, SIGNAL(clicked(int, Qt::MouseButton, const QPoint&)), this, SLOT(onHHeaderClicked(int, Qt::MouseButton, const QPoint&)));
     connect(header, SIGNAL(sectionMoved(int, int, int)), this, SLOT(onHHeaderMoved(int, int, int)));
-    header = dynamic_cast<QCustomHeaderView*>(verticalHeader());
-    connect(header, SIGNAL(clicked(int, Qt::MouseButton, const QPoint&)), this, SLOT(onVHeaderClicked(int, Qt::MouseButton, const QPoint&)));
-    connect(header, SIGNAL(sectionMoved(int, int, int)), this, SLOT(onVHeaderMoved(int, int, int)));
+    // connections with the vertical header
+    connect(pVHeader, SIGNAL(clicked(int, Qt::MouseButton, const QPoint&)), this, SLOT(onVHeaderClicked(int, Qt::MouseButton, const QPoint&)));
+    connect(pVHeader, SIGNAL(sectionMoved(int, int, int)), this, SLOT(onVHeaderMoved(int, int, int)));
+    connect(pVHeader, SIGNAL(sectionDoubleClicked(int)), this, SLOT(onCharacterDoubleClicked(int)));
+    connect(pVHeader, SIGNAL(toolTipRequested(int, const QPoint&)), this, SLOT(onVHeaderToolTipRequested(int, const QPoint&)));
+    // self-connections
     connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(on_itemSelectionChanged()));
     connect(this, SIGNAL(cellChanged(int,int)), this, SLOT(onCellChanged(int,int)));
+
+    // sets the text of the menus and a few other things
+    retranslate();
 }
 
 QCustomTableWidget::~QCustomTableWidget()
@@ -262,14 +266,18 @@ void QCustomTableWidget::updateDisplay(int row, int column)
     for (CharacterList::iterator it = pCharacters->begin(); it != pCharacters->end(); it++)
     {
         insertRow(j);
-        setVerticalHeaderItem(j, new QTableWidgetItem(headerText((*it).name().c_str(), (*it).shortDescription().c_str())));
-        // creating items
-        for (k=0;k<i;k++)
+        Character *character = (*it);
+        // open the associated note if necessary
+        Note *note = character->note();
+        if (note->visible())
         {
+            emit noteToOpen(note);
         }
+        // create the header
+        setVerticalHeaderItem(j, new QTableWidgetItem(headerText(character->name().c_str(), character->shortDescription().c_str())));
         // setting values
         k = 0;
-        for (Character::PropertyIterator itProperty = (*it).begin(); itProperty != (*it).end() && k<i; itProperty++)
+        for (Character::PropertyIterator itProperty = character->begin(); itProperty != character->end() && k<i; itProperty++)
         {
             setItem(j,k,new QTableWidgetItem((*itProperty).c_str()));
             k++;
@@ -310,14 +318,14 @@ void QCustomTableWidget::onCellChanged(int logicalRow, int logicalColumn)
     int column = visualColumn(logicalColumn);
     if (pCharacters)
     {
-        Character &charact = (*pCharacters)[row];
-        for (int i=charact.propertyNumber(); i<column+1; i++)
+        Character *charact = (*pCharacters)[row];
+        for (int i=charact->propertyNumber(); i<column+1; i++)
         {
-            charact.addProperty("0");
+            charact->addProperty("0");
         }
-        std::string value = charact.property(column);
+        std::string value = charact->property(column);
         std::string newValue = item(logicalRow, logicalColumn)->text().toStdString();
-        charact.property(column) = newValue;
+        charact->property(column) = newValue;
         if (iCreatedCells)
         {
             // we ignore the newly created cells
@@ -403,9 +411,9 @@ void QCustomTableWidget::addCharacter(int index)
         // updating the CharacterList
         if (pCharacters)
         {
-            Character character(pChangeCharacterDial->name().toStdString(), pChangeCharacterDial->shortDescription().toStdString());
+            Character *character = new Character(pChangeCharacterDial->name().toStdString(), pChangeCharacterDial->shortDescription().toStdString());
             pCharacters->add(character,index+1);
-            emit modificationDone(new CharacterModification(pCharacters, new Character(character), index+1, true));
+            emit modificationDone(new CharacterModification(pCharacters, index+1));
         }
 
         // updating the display
@@ -453,10 +461,11 @@ void QCustomTableWidget::addProperty(int index)
         {
             for (CharacterList::iterator it=pCharacters->begin(); it != pCharacters->end(); it++)
             {
-                if ((unsigned int)index+1 < it->propertyNumber())
+                Character *character = *it;
+                if ((unsigned int)index+1 < character->propertyNumber())
                 {
                     // adding a property
-                    it->addProperty("0",index+1);
+                    character->addProperty("0",index+1);
                 }
             } 
         }
@@ -494,7 +503,9 @@ void QCustomTableWidget::removeCharacter(int index)
         // updating the CharacterList
         if (pCharacters)
         {
-            emit modificationDone(new CharacterModification(pCharacters, new Character((*pCharacters)[index]), index, false));
+            Character *character = (*pCharacters)[index];
+            emit modificationDone(new CharacterModification(pCharacters, character, index));
+            emit noteToDelete(character->note());
             pCharacters->remove(index);
         }
         if (index == rowCount())
@@ -516,10 +527,11 @@ void QCustomTableWidget::removeProperty(int index)
         {
             for (CharacterList::iterator it = pCharacters->begin(); it != pCharacters->end(); it++)
             {
-                if ((unsigned int)index < it->propertyNumber())
+                Character *character = *it;
+                if ((unsigned int)index < character->propertyNumber())
                 {
-                    values.push_back(it->property(index));
-                    it->removeProperty(index);
+                    values.push_back(character->property(index));
+                    character->removeProperty(index);
                 }
             } 
         }
@@ -546,15 +558,15 @@ void QCustomTableWidget::editCharacter(int index)
         scrollTo(index, -1);
         if (pCharacters)
         {
-            Character &character = (*pCharacters)[index];
-            if(pChangeCharacterDial->exec(&character)==QDialog::Accepted)
+            Character *character = (*pCharacters)[index];
+            if(pChangeCharacterDial->exec(character)==QDialog::Accepted)
             {
                 // updating the CharacterList
-                std::string name = character.name();
-                std::string shortDescription = character.shortDescription();
-                character.setName(pChangeCharacterDial->name().toStdString());
-                character.setShortDescription(pChangeCharacterDial->shortDescription().toStdString());
-                emit modificationDone(new CharacterModification(pCharacters, name, shortDescription, character.name(), character.shortDescription(), index));
+                std::string name = character->name();
+                std::string shortDescription = character->shortDescription();
+                character->setName(pChangeCharacterDial->name().toStdString());
+                character->setShortDescription(pChangeCharacterDial->shortDescription().toStdString());
+                emit modificationDone(new CharacterModification(pCharacters, name, shortDescription, character->name(), character->shortDescription(), index));
                 QTableWidgetItem *rowHeaderItem = verticalHeaderItem(logicalRow(index));
                 rowHeaderItem->setText(headerText(pChangeCharacterDial->name(), pChangeCharacterDial->shortDescription()));
             }
@@ -630,7 +642,7 @@ void QCustomTableWidget::onHHeaderMoved(int, int oldColumn, int newColumn)
     {
         for (CharacterList::iterator it = pCharacters->begin(); it != pCharacters->end(); it++)
         {
-            it->moveProperty(oldColumn, newColumn);
+            (*it)->moveProperty(oldColumn, newColumn);
         }
     }
 }
@@ -722,6 +734,7 @@ void QCustomTableWidget::updateModification(CharacterModification *modification,
                                                         switch (modification->action())
                                                         {
                                                             case Modification::aAddition:   row = modification->index()-1;
+                                                                                            emit noteToDelete(modification->character()->note());
                                                                                             break;
                                                             default:    row = modification->index();
                                                         }
@@ -731,6 +744,7 @@ void QCustomTableWidget::updateModification(CharacterModification *modification,
                                                         switch (modification->action())
                                                         {
                                                             case Modification::aDeletion:   row = modification->index()-1;
+                                                                                            emit noteToDelete(modification->character()->note());
                                                                                             break;
                                                             case Modification::aMovement:   row = modification->newIndex();
                                                                                             break;
@@ -789,6 +803,7 @@ void QCustomTableWidget::retranslate()
     actionEditRow->setText(QApplication::translate("customTable","&Edit",0));
     actionEditRow->setStatusTip(QApplication::translate("customTable","Edit the character",0));
     actionEditRow->setShortcut(QString("Ctrl+Shift+F2"));
+    pVHeader->setStatusTip(QApplication::translate("customTable", "Double click to display the note associated with a character", 0));
 }
 
 void QCustomTableWidget::changeEvent(QEvent *e)
@@ -826,3 +841,24 @@ int QCustomTableWidget::sizeHintForColumn(int column) const
 
     return hint;
 }
+
+void QCustomTableWidget::onCharacterDoubleClicked(int index)
+{
+    if (index != -1)
+    {
+        int row = visualRow(index);
+        emit noteToOpen((*pCharacters)[row]->note());
+    }
+}
+
+void QCustomTableWidget::onVHeaderToolTipRequested(int index, const QPoint &position)
+{
+    if (index != -1)
+    {
+        QToolTip::showText(position, (*pCharacters)[index]->note()->title().c_str());
+    }
+    else
+    {
+        QToolTip::hideText();
+    }
+}
diff --git a/sources/widgets/QCustomTableWidget.h b/sources/widgets/QCustomTableWidget.h
index a6fdb05..2781d82 100644
--- a/sources/widgets/QCustomTableWidget.h
+++ b/sources/widgets/QCustomTableWidget.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2011-2017 Vincent Prat & Simon Nicolas
+* Copyright © 2011-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -28,6 +28,7 @@
 #include "PropertyList.h"
 #include "CharacterList.h"
 #include "CharacterModification.h"
+#include "QCustomHeaderView.h"
 
 /*!
  * \brief Custom table widget
@@ -69,6 +70,8 @@ class QCustomTableWidget: public QTableWidget
         bool bUpdate;
         //! Number of recently created cells
         int iCreatedCells;
+        //! Vertical header
+        QCustomHeaderView *pVHeader;
         //! Type of selection
         QAbstractItemView::SelectionBehavior eSelected;
     protected:
@@ -76,22 +79,22 @@ class QCustomTableWidget: public QTableWidget
          * \brief Event raised when the table is clicked
          * \param e Mouse event
          */
-        void mousePressEvent(QMouseEvent *e);
+        void mousePressEvent(QMouseEvent *e) override;
         /*!
          * \brief KeyReleaseEvent handler
          * \param e Key event
          */
-        void keyReleaseEvent(QKeyEvent *e);
+        void keyReleaseEvent(QKeyEvent *e) override;
         /*!
          * \brief DoubleClickEvent handler
          * \param e Mouse event
          */
-        void mouseDoubleClickEvent(QMouseEvent *e);
+        void mouseDoubleClickEvent(QMouseEvent *e) override;
         /*!
          * \brief ChangeEvent handler
          * \param e Event to handle
          */
-        void changeEvent(QEvent *e);
+        void changeEvent(QEvent *e) override;
         /*!
          * \brief Addition of a property
          * \param index Index where to add the property
@@ -139,7 +142,7 @@ class QCustomTableWidget: public QTableWidget
          * \brief Size hint for columns taking into account unvisible ones
          * \param column Column to resize
          */
-        int sizeHintForColumn(int column) const;
+        int sizeHintForColumn(int column) const override;
     protected slots:
         /*!
          * \brief Slot for when a cell changes 
@@ -173,10 +176,21 @@ class QCustomTableWidget: public QTableWidget
          * \param newRow New visual row
          */
         void onVHeaderMoved(int, int oldRow, int newRow);
+        /*!
+         * \brief Slot for when a character is double-clicked
+         * \param index Index of the clicked row
+         */
+        void onCharacterDoubleClicked(int index);
         /*!
          * \brief Slot for when the selection changes 
          */
         void on_itemSelectionChanged();
+        /*!
+         * \brief Slot for when the vertical header requests a tool tip
+         * \param index Index of the row
+         * \param position Global position of the event
+         */
+        void onVHeaderToolTipRequested(int index, const QPoint &position);
     public:
         /*!
          * \brief Constructor of the widget
@@ -213,6 +227,20 @@ class QCustomTableWidget: public QTableWidget
          * This signal is sent when the tree is modified
          */
         void modificationDone(Modification *modification);
+        /*!
+         * \brief Signal to open a note
+         * \param note Note we want to open
+         *
+         * This signal is sent when a note has to be opened
+         */
+        void noteToOpen(Note *note);
+        /*!
+         * \brief Signal to delete a note
+         * \param note Note we want to delete
+         *
+         * This signal is sent when a note has to be deleted
+         */
+        void noteToDelete(Note *note);
     public slots:
         /*!
          * \brief Update of the display
diff --git a/sources/widgets/QCustomTextEdit.cpp b/sources/widgets/QCustomTextEdit.cpp
index 960bb11..d78d351 100644
--- a/sources/widgets/QCustomTextEdit.cpp
+++ b/sources/widgets/QCustomTextEdit.cpp
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2012-2013 Vincent Prat & Simon Nicolas
+* Copyright © 2012-2019 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -23,27 +23,28 @@
 
 using namespace std;
 
-QCustomTextEdit::QCustomTextEdit(QWidget *parent): QTextEdit(parent), pNotes(0), sStatus(sMove), bDropped(false), bPasted(false), bCut(false)
+QCustomTextEdit::QCustomTextEdit(QWidget *parent, QObject *filter): QTextEdit(parent), pNote(0), sStatus(sMove), bDropped(false), bPasted(false), bCut(false)
 {
     connect(this, SIGNAL(textChanged()), this, SLOT(onTextChanged()));
+    installEventFilter(filter);
 }
 
-void QCustomTextEdit::setNotes(string *text)
+void QCustomTextEdit::setNote(Note *note)
 {
-    pNotes = text;
+    pNote = note;
     updateDisplay();
 }
 
 void QCustomTextEdit::updateDisplay(int position, int length)
 {
-    if (pNotes)
+    if (pNote)
     {
         QScrollBar *hbar = horizontalScrollBar();
         QScrollBar *vbar = verticalScrollBar();
         int h = hbar->value();
         int v = vbar->value();
         bUpdate = true;
-        setText(pNotes->c_str());
+        setText(pNote->text().c_str());
         bUpdate = false;
         sStatus = sMove;
         sRef = toPlainText();
@@ -52,8 +53,8 @@ void QCustomTextEdit::updateDisplay(int position, int length)
             hbar->setValue(h);
             vbar->setValue(v);
             QTextCursor cursor = textCursor();
-            cursor.setPosition(QString(pNotes->substr(0, position).c_str()).length());
-            cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, QString(pNotes->substr(position, length).c_str()).length());
+            cursor.setPosition(QString(pNote->text().substr(0, position).c_str()).length());
+            cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, QString(pNote->text().substr(position, length).c_str()).length());
             setTextCursor(cursor);
         }
     }
@@ -62,10 +63,10 @@ void QCustomTextEdit::updateDisplay(int position, int length)
 #include <algorithm>
 void QCustomTextEdit::onTextChanged()
 {
-    if (pNotes)
+    if (pNote)
     {
         QString sText = toPlainText();
-        *pNotes = sText.toStdString();
+        pNote->text() = sText.toStdString();
         if (sRef == sText || bDropped || bUpdate)
         {
             bPasted = false;
@@ -156,7 +157,7 @@ void QCustomTextEdit::onTextChanged()
                 sModif = sText.mid(index, l2 - rindex - index);
                 sOldModif = sRef.mid(index, l1 - rindex - index);
                 iIndex = sRef.left(index).toStdString().length();
-                emit modificationDone(new NoteModification(*pNotes, sOldModif.toStdString(), sModif.toStdString(), iIndex));
+                emit modificationDone(new NoteModification(*pNote, sOldModif.toStdString(), sModif.toStdString(), iIndex));
                 sRef = sText;
             }
         }
@@ -167,13 +168,13 @@ void QCustomTextEdit::onTextChanged()
 
 void QCustomTextEdit::checkModification()
 {
-    if (pNotes)
+    if (pNote)
     {
         switch (sStatus)
         {
-            case sInsertion:    emit modificationDone(new NoteModification(*pNotes, Modification::aAddition, sModif.toStdString(), iIndex));
+            case sInsertion:    emit modificationDone(new NoteModification(*pNote, Modification::aAddition, sModif.toStdString(), iIndex));
                                 break;
-            case sDeletion:     emit modificationDone(new NoteModification(*pNotes, Modification::aDeletion, sModif.toStdString(), iIndex));
+            case sDeletion:     emit modificationDone(new NoteModification(*pNote, Modification::aDeletion, sModif.toStdString(), iIndex));
                                 break;
             default:    return;
         }
@@ -248,9 +249,9 @@ void QCustomTextEdit::dropEvent(QDropEvent *e)
     if (e->source()->parent() == this)
     {
         QString sNewText = toPlainText();
-        if (pNotes && sText != sNewText)
+        if (pNote && sText != sNewText)
         {
-            emit modificationDone(new NoteModification(*pNotes, iIndex, iNewIndex, iLength));
+            emit modificationDone(new NoteModification(*pNote, iIndex, iNewIndex, iLength));
             sRef = sNewText;
         }
     }
diff --git a/sources/widgets/QCustomTextEdit.h b/sources/widgets/QCustomTextEdit.h
index 30e77fe..7145a5d 100644
--- a/sources/widgets/QCustomTextEdit.h
+++ b/sources/widgets/QCustomTextEdit.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2012-2013 Vincent Prat & Simon Nicolas
+* Copyright © 2012-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -34,18 +34,24 @@ class QCustomTextEdit: public QTextEdit
         /*!
          * \brief Constructor
          * \param parent Parent widget
+         * \param filter Event filter
          */
-        QCustomTextEdit(QWidget *parent=0);
+        QCustomTextEdit(QWidget *parent=0, QObject *filter=0);
         /*!
-         * \brief Setter for the underlying notes
-         * \param text Text of the notes
+         * \brief Setter for the underlying note
+         * \param note Note
          */
-        void setNotes(std::string *text); 
+        void setNote(Note *note);
         /*!
          * \brief Indicator of unregistered modifications
          * \return True if there is an unregistered modification
          */
         bool unregisteredModification() const;
+        /*!
+         * \brief Getter for the underlying note
+         * \return Pointer to the note
+         */
+        inline Note* note();
     public slots:
         /*!
          * \brief Update of the display
@@ -84,38 +90,38 @@ class QCustomTextEdit: public QTextEdit
          *
          * Stores the text to compare when focus goes out
          */
-        void focusInEvent(QFocusEvent *e);
+        void focusInEvent(QFocusEvent *e) override;
         /*!
          * \brief FocusOut event handler
          * \param e Event to handle
          *
          * Checks if the text has been modified before releasing focus
          */
-        void focusOutEvent(QFocusEvent *e);
+        void focusOutEvent(QFocusEvent *e) override;
         /*!
          * \brief KeyPress event handler
          * \param e Event to handle
          *
          * Decomposes edition in several modifications (insertion, deletion, etc.)
          */
-        void keyPressEvent(QKeyEvent *e);
+        void keyPressEvent(QKeyEvent *e) override;
         /*!
          * \brief MousePress event handler
          * \param e Event to handle
          *
          * Works together with keyPressEvent
          */
-        void mousePressEvent(QMouseEvent *e);
+        void mousePressEvent(QMouseEvent *e) override;
         /*!
          * \brief DragEnter event handler
          * \param e Event to handle
          */
-        void dragEnterEvent(QDragEnterEvent *e);
+        void dragEnterEvent(QDragEnterEvent *e) override;
         /*!
          * \brief Drop event handler
          * \param e Event to handle
          */
-        void dropEvent(QDropEvent *e);
+        void dropEvent(QDropEvent *e) override;
     protected slots:
         /*!
          * \brief Slot for when the text has changed
@@ -136,8 +142,8 @@ class QCustomTextEdit: public QTextEdit
         };
         //! Reference text
         QString sRef;
-        //! Underlying notes
-        std::string *pNotes;
+        //! Underlying note
+        Note *pNote;
         //! Edition status
         Status sStatus; 
         //! Modified string
@@ -174,4 +180,9 @@ class QCustomTextEdit: public QTextEdit
         void unregistered();
 };
 
+Note* QCustomTextEdit::note()
+{
+    return pNote;
+}
+
 #endif
diff --git a/sources/widgets/QCustomTreeWidget.cpp b/sources/widgets/QCustomTreeWidget.cpp
index 5c21472..12e5c0e 100644
--- a/sources/widgets/QCustomTreeWidget.cpp
+++ b/sources/widgets/QCustomTreeWidget.cpp
@@ -25,6 +25,7 @@
 #include <exception>
 #include <QScrollBar>
 #include <QFileDialog>
+#include <QToolTip>
 #include <sstream>
 
 using namespace std;
@@ -86,11 +87,11 @@ void QCustomTreeWidget::mouseDoubleClickEvent(QMouseEvent *e)
 
 void QCustomTreeWidget::launchItem(QTreeWidgetItem *qItem)
 {
-    Item *item = dynamic_cast<QCustomTreeWidgetItem*>(qItem)->branch()->item();
+    Item *item = static_cast<QCustomTreeWidgetItem*>(qItem)->branch()->item();
     switch (item->type())
     {
         case Item::tSound:  {
-                                SoundItem *soundItem = dynamic_cast<SoundItem*>(item);
+                                SoundItem *soundItem = static_cast<SoundItem*>(item);
                                 if (pmMethod == pmNone)
                                 {
                                     QMessageBox::critical(this,QApplication::translate("mainWindow","Error",0), QApplication::translate("customTree","Audio files can be played only in the Music and Sound effects modules.",0));
@@ -102,8 +103,8 @@ void QCustomTreeWidget::launchItem(QTreeWidgetItem *qItem)
                                 }
                                 break;
                             }
-        case Item::tImage: {
-                                ImageItem *imageItem = dynamic_cast<ImageItem*>(item);
+        case Item::tImage:  {
+                                ImageItem *imageItem = static_cast<ImageItem*>(item);
                                 ImageWindow *image = new ImageWindow(imageItem->fileName(),this);
                                 if (image->error())
                                 {
@@ -111,7 +112,11 @@ void QCustomTreeWidget::launchItem(QTreeWidgetItem *qItem)
                                     delete image;
                                 }
                                 break;
-                             }
+                            }
+        case Item::tNote:   {
+                                NoteItem *noteItem = static_cast<NoteItem*>(item);
+                                emit noteToOpen(noteItem->note());
+                            }
         default:            break;
     }
 }
@@ -132,7 +137,7 @@ void QCustomTreeWidget::mousePressEvent(QMouseEvent *e)
         case Qt::RightButton:   if (item)
                                 {
                                     setCurrentItem(item);
-                                    QCustomTreeWidgetItem *qItem = dynamic_cast<QCustomTreeWidgetItem*>(item);
+                                    QCustomTreeWidgetItem *qItem = static_cast<QCustomTreeWidgetItem*>(item);
                                     Item *treeItem = qItem->branch()->item();
                                     Item::Type type = treeItem->type();
                                     switch (type)
@@ -149,16 +154,21 @@ void QCustomTreeWidget::mousePressEvent(QMouseEvent *e)
                                                                 actionLaunch->setVisible(true);
                                                             }
                                                             break;
-                                        case Item::tImage:      actionLaunch->setIcon(QIcon(":/data/images/image.svg"));
-                                                                actionLaunch->setStatusTip(QApplication::translate("customTree","Display the image",0));
-                                                                actionLaunch->setText(QApplication::translate("customTree","Disp&lay",0));
-                                                                actionLaunch->setVisible(true);
-                                                                break;
+                                        case Item::tImage:  actionLaunch->setIcon(QIcon(":/data/images/image.svg"));
+                                                            actionLaunch->setStatusTip(QApplication::translate("customTree","Display the image",0));
+                                                            actionLaunch->setText(QApplication::translate("customTree","Disp&lay",0));
+                                                            actionLaunch->setVisible(true);
+                                                            break;
+                                        case Item::tNote:   actionLaunch->setIcon(QIcon(":/data/images/text.svg")),
+                                                            actionLaunch->setStatusTip(QApplication::translate("customTree", "Display the note", 0));
+                                                            actionLaunch->setText(QApplication::translate("customTree", "Disp&lay", 0));
+                                                            actionLaunch->setVisible(true);
+                                                            break;
                                         default:    actionLaunch->setVisible(false);
                                                     break;
                                     }
                                     // export
-                                    actionExport->setVisible(Item::is(type, Item::tFile) && dynamic_cast<FileItem*>(treeItem)->isIncluded());
+                                    actionExport->setVisible(Item::is(type, Item::tFile) && static_cast<FileItem*>(treeItem)->isIncluded());
                                     // execute menu
                                     QAction* action = menuIcons->exec(e->globalPos());
                                     if (action == actionNone)
@@ -228,7 +238,7 @@ void QCustomTreeWidget::keyReleaseEvent(QKeyEvent *e)
     if (qItem)
     {
         scrollTo(qItem);
-        QCustomTreeWidgetItem *customItem = dynamic_cast<QCustomTreeWidgetItem*>(qItem);
+        QCustomTreeWidgetItem *customItem = static_cast<QCustomTreeWidgetItem*>(qItem);
         switch (e->key())
         {
             case Qt::Key_F2:    if (!bEditing)
@@ -280,7 +290,7 @@ void QCustomTreeWidget::keyReleaseEvent(QKeyEvent *e)
                                 break;
             case Qt::Key_F8:    changeState(customItem, Item::sSuccess);
                                 break;
-            default:    QTreeWidget::keyReleaseEvent(e); break; 
+            default:    QTreeWidget::keyReleaseEvent(e); break;
         }
     }
 }
@@ -289,7 +299,7 @@ void QCustomTreeWidget::on_itemChanged(QTreeWidgetItem* item, int column)
 {
     if (pTree && item && column == 0)
     {
-        Branch *branch = dynamic_cast<QCustomTreeWidgetItem*>(item)->branch();
+        Branch *branch = static_cast<QCustomTreeWidgetItem*>(item)->branch();
         if (bEditing && branch->item()->content() != item->text(0).toStdString())
         {
             string content = branch->item()->content();
@@ -317,35 +327,48 @@ void QCustomTreeWidget::updateDisplay(const string &indices)
         int h = vbar->value();
         // iterating over the tree to populate the widget
         vector<QCustomTreeWidgetItem*> items;
-        QCustomTreeWidgetItem* item, *focusItem=0;
-        int depth=0;        
+        QCustomTreeWidgetItem* widgetItem, *focusItem=0;
+        Branch *branch;
+        Item *item;
+        int depth=0;
         for (Tree::iterator it = pTree->begin(); it != pTree->end(); it++)
         {
             depth = it.depth();
+            branch = it.branch();
+            item = branch->item();
             if (depth==0)
             {
-                item = new QCustomTreeWidgetItem(this, it.branch());
+                widgetItem = new QCustomTreeWidgetItem(this, branch);
             }
             else
             {
-                item = new QCustomTreeWidgetItem(items[depth-1], it.branch());
+                widgetItem = new QCustomTreeWidgetItem(items[depth-1], branch);
             }
             if (items.size() > (unsigned int)(depth))
             {
-                items[depth] = item;
+                items[depth] = widgetItem;
             }
             else
             {
-                items.push_back(item);
+                items.push_back(widgetItem);
             }
             // expand the item if needed
-            if (it.branch()->item()->expanded())
+            if (item->expanded())
             {
-                expandItem(item);
+                expandItem(widgetItem);
+            }
+            // open notes
+            if (item->type() == Item::tNote)
+            {
+                Note* note = static_cast<NoteItem*>(item)->note();
+                if (note->visible())
+                {
+                    emit noteToOpen(note);
+                }
             }
             if (!focusItem && indices == it.indices())
             {
-                focusItem = item;
+                focusItem = widgetItem;
             }
         }
         resizeColumnToContents(0);
@@ -365,8 +388,10 @@ void QCustomTreeWidget::updateDisplay(const string &indices)
 
 void QCustomTreeWidget::deleteItem(QTreeWidgetItem *item)
 {
-    Branch *branch = dynamic_cast<QCustomTreeWidgetItem*>(item)->branch();
-    // stop the music if the item is a SoundItem
+    Branch *branch = static_cast<QCustomTreeWidgetItem*>(item)->branch();
+    // delete notes in the branch
+    deleteNotes(branch);
+    // stop the music if the item is or contains a SoundItem
     if (pmMethod == pmMusic)
     {
         stopMusic(branch);
@@ -411,25 +436,25 @@ void QCustomTreeWidget::dropEvent(QDropEvent *e)
         // now we have an item, we check whether we are above, below or on it
         QRect rect = visualRect(index);
         const int margin = 2;
-       
-        string indices = pTree->indicesOf(dynamic_cast<QCustomTreeWidgetItem*>(pDragSource)->branch()); 
+
+        string indices = pTree->indicesOf(static_cast<QCustomTreeWidgetItem*>(pDragSource)->branch());
         string newIndices;
         // different positions
         if (pos.y() - rect.top() < margin)
         {
             // we are above it
-            newIndices = pTree->indicesOf(dynamic_cast<QCustomTreeWidgetItem*>(item)->branch());
+            newIndices = pTree->indicesOf(static_cast<QCustomTreeWidgetItem*>(item)->branch());
         }
         else if (rect.bottom() - pos.y() < margin)
         {
             // we are below it
-            newIndices = pTree->indicesOfNext(dynamic_cast<QCustomTreeWidgetItem*>(item)->branch());
+            newIndices = pTree->indicesOfNext(static_cast<QCustomTreeWidgetItem*>(item)->branch());
         }
         else if (rect.contains(pos, true))
         {
             // we are on it : new child
             stringstream buf(stringstream::in|stringstream::out);
-            Branch *branch = dynamic_cast<QCustomTreeWidgetItem*>(item)->branch();
+            Branch *branch = static_cast<QCustomTreeWidgetItem*>(item)->branch();
             buf << pTree->indicesOf(branch);
             // we want to add it as the last child
             buf << "_" << branch->tree().numberOfChildren();
@@ -486,6 +511,22 @@ void QCustomTreeWidget::addItem(QCustomTreeWidgetItem *item, bool edition)
                                             }
                     case Item::tImage:      newItem = new ImageItem(pItemDial->text().toStdString(), pItemDial->state(), false, pItemDial->fileName().toStdString());
                                             break;
+                    case Item::tNote:       {
+                                                Note *note = 0;
+                                                if (edition)
+                                                {
+                                                    Item *iItem = item->branch()->item();
+                                                    if (iItem->type() == Item::tNote)
+                                                    {
+                                                        note = static_cast<NoteItem*>(iItem)->note();
+                                                    }
+                                                }
+                                                NoteItem *noteItem = new NoteItem(pItemDial->text().toStdString(), pItemDial->state(), false, note);
+                                                note = noteItem->note();
+                                                note->setTitle(noteItem->content());
+                                                newItem = noteItem;
+                                                break;
+                                            }
                     default:                newItem = new Item(pItemDial->text().toStdString(),pItemDial->state());
                                             break;
                 }
@@ -506,14 +547,19 @@ void QCustomTreeWidget::addItem(QCustomTreeWidgetItem *item, bool edition)
                 if (edition)
                 {
                     Item *iItem = item->branch()->item();
-                    emit modificationDone(new TreeModification(*pTree, iItem, ItemFactory::copyItem(newItem), pTree->indicesOf(item->branch())));
-                    // stopping the music if necessary
-                    if (pmMethod == pmMusic && iItem->type() == Item::tSound)
+                    emit modificationDone(new TreeModification(*pTree, iItem, pTree->indicesOf(item->branch())));
+                    if (iItem->type() == Item::tNote && newItem->type() != Item::tNote)
+                    {
+                        // delete the note
+                        emit noteToDelete(static_cast<NoteItem*>(iItem)->note());
+                    }
+                    else if (pmMethod == pmMusic && iItem->type() == Item::tSound)
                     {
-                        SoundItem *siItem = dynamic_cast<SoundItem*>(iItem);
+                        // stopping the music if necessary
+                        SoundItem *siItem = static_cast<SoundItem*>(iItem);
                         if (newItem->type() == Item::tSound)
                         {
-                            SoundItem* newSItem = dynamic_cast<SoundItem*>(newItem);
+                            SoundItem* newSItem = static_cast<SoundItem*>(newItem);
                             if (newSItem->fileName() != siItem->fileName())
                             {
                                 emit fileToStop(siItem);
@@ -530,11 +576,11 @@ void QCustomTreeWidget::addItem(QCustomTreeWidgetItem *item, bool edition)
                     }
                     // replacement
                     item->branch()->setItem(newItem);
-                    item->updateDisplay(); 
+                    item->updateDisplay();
                     scrollTo(item);
                 }
                 else
-                {    
+                {
                     // new item is created
                     QCustomTreeWidgetItem *newQItem = 0;
                     switch (pItemDial->selectionResult())
@@ -545,7 +591,7 @@ void QCustomTreeWidget::addItem(QCustomTreeWidgetItem *item, bool edition)
                                                         if (parent)
                                                         {
                                                             newBranch = parent->tree().insert(parent->tree().indexOf(item->branch())+1,newItem);
-                                                            newQItem = new QCustomTreeWidgetItem(dynamic_cast<QCustomTreeWidgetItem*>(item->parent()),newBranch,item);
+                                                            newQItem = new QCustomTreeWidgetItem(static_cast<QCustomTreeWidgetItem*>(item->parent()),newBranch,item);
                                                         }
                                                         else
                                                         {
@@ -576,7 +622,7 @@ void QCustomTreeWidget::addItem(QCustomTreeWidgetItem *item, bool edition)
             // creating the modification
             if (!edition)
             {
-                emit modificationDone(new TreeModification(*pTree, ItemFactory::copyItem(newItem), pTree->indicesOf(newBranch)));
+                emit modificationDone(new TreeModification(*pTree, pTree->indicesOf(newBranch)));
             }
             resizeColumnToContents(0);
         }
@@ -599,7 +645,7 @@ void QCustomTreeWidget::setPlayingMethod(QWidget *player, PlayingMethod playingM
                         // connection for changing without modifying playback
                         connect(this, SIGNAL(fileToChange(const SoundItem*, const SoundItem*)), player, SLOT(changeCurrentMusic(const SoundItem*, const SoundItem*)));
                         break;
-        default:        break;                        
+        default:        break;
     }
 }
 
@@ -610,13 +656,13 @@ QCustomTreeWidget::PlayingMethod QCustomTreeWidget::playingMethod() const
 
 void QCustomTreeWidget::onItemExpanded(QTreeWidgetItem *item)
 {
-    dynamic_cast<QCustomTreeWidgetItem*>(item)->branch()->item()->setExpanded(true);
+    static_cast<QCustomTreeWidgetItem*>(item)->branch()->item()->setExpanded(true);
     resizeColumnToContents(0);
 }
 
 void QCustomTreeWidget::onItemCollapsed(QTreeWidgetItem *item)
 {
-    dynamic_cast<QCustomTreeWidgetItem*>(item)->branch()->item()->setExpanded(false);
+    static_cast<QCustomTreeWidgetItem*>(item)->branch()->item()->setExpanded(false);
     resizeColumnToContents(0);
 }
 
@@ -648,26 +694,35 @@ void QCustomTreeWidget::updateModification(TreeModification *modification, bool
             case Modification::aAddition:
                 {
                     indices = modification->deletedIndices();
-                    // stopping music if necessary
                     Item *item = modification->undoneItem();
-                    if (pmMethod == pmMusic && item->type() == Item::tSound)
+                    if (item->type() == Item::tNote)
+                    {
+                        // deleting note
+                        emit noteToDelete(static_cast<NoteItem*>(item)->note());
+                    }
+                    else if (pmMethod == pmMusic && item->type() == Item::tSound)
                     {
-                        emit fileToStop(dynamic_cast<SoundItem*>(item));
+                        // stopping music if necessary
+                        emit fileToStop(static_cast<SoundItem*>(item));
                     }
-                    modification->freeUndoneItem();
                     break;
                 }
             case Modification::aEdition:    if (modification->editionType() == TreeModification::etFull)
                                             {
-                                                // stopping music if necessary
                                                 Item *item = modification->undoneItem();
-                                                if (pmMethod == pmMusic && item->type() == Item::tSound)
+                                                if (item->type() == Item::tNote && modification->currentItem()->type() != Item::tNote)
                                                 {
-                                                    SoundItem *sItem = dynamic_cast<SoundItem*>(item);
+                                                    // deleting note
+                                                    emit noteToDelete(static_cast<NoteItem*>(item)->note());
+                                                }
+                                                else if (pmMethod == pmMusic && item->type() == Item::tSound)
+                                                {
+                                                    // stopping music if necessary
+                                                    SoundItem *sItem = static_cast<SoundItem*>(item);
                                                     Item *oldItem = modification->currentItem();
                                                     if (oldItem->type() == Item::tSound)
                                                     {
-                                                        SoundItem *oldSItem = dynamic_cast<SoundItem*>(oldItem);
+                                                        SoundItem *oldSItem = static_cast<SoundItem*>(oldItem);
                                                         if (oldSItem->fileName() != sItem->fileName())
                                                         {
                                                             emit fileToStop(sItem);
@@ -682,7 +737,6 @@ void QCustomTreeWidget::updateModification(TreeModification *modification, bool
                                                         emit fileToStop(sItem);
                                                     }
                                                 }
-                                                modification->freeUndoneItem();
                                             }
             default:    indices = modification->indices();
         }
@@ -692,6 +746,7 @@ void QCustomTreeWidget::updateModification(TreeModification *modification, bool
         switch (modification->action())
         {
             case Modification::aDeletion:   indices = modification->deletedIndices();
+                                            deleteNotes(modification->branch());
                                             if (pmMethod == pmMusic)
                                             {
                                                 stopMusic(modification->branch());
@@ -701,15 +756,20 @@ void QCustomTreeWidget::updateModification(TreeModification *modification, bool
                                             break;
             case Modification::aEdition:    if (modification->editionType() == TreeModification::etFull)
                                             {
-                                                // stopping music if necessary
-                                                Item *item = modification->undoneItem();
-                                                if (pmMethod == pmMusic && item->type() == Item::tSound)
+                                                Item *item = modification->item();
+                                                if (item->type() == Item::tNote && modification->currentItem()->type() != Item::tNote)
                                                 {
-                                                    SoundItem *sItem = dynamic_cast<SoundItem*>(item);
+                                                    // deleting note
+                                                    emit noteToDelete(static_cast<NoteItem*>(item)->note());
+                                                }
+                                                else if (pmMethod == pmMusic && item->type() == Item::tSound)
+                                                {
+                                                    // stopping music if necessary
+                                                    SoundItem *sItem = static_cast<SoundItem*>(item);
                                                     Item *newItem = modification->currentItem();
                                                     if (newItem->type() == Item::tSound)
                                                     {
-                                                        SoundItem *newSItem = dynamic_cast<SoundItem*>(newItem);
+                                                        SoundItem *newSItem = static_cast<SoundItem*>(newItem);
                                                         if (newSItem->fileName() != sItem->fileName())
                                                         {
                                                             emit fileToStop(sItem);
@@ -724,14 +784,13 @@ void QCustomTreeWidget::updateModification(TreeModification *modification, bool
                                                         emit fileToStop(sItem);
                                                     }
                                                 }
-                                                modification->freeUndoneItem();
                                             }
             default:    indices = modification->indices();
         }
     }
     updateDisplay(indices);
     setFocus(Qt::OtherFocusReason);
-} 
+}
 
 void QCustomTreeWidget::changeEvent(QEvent *e)
 {
@@ -772,7 +831,7 @@ void QCustomTreeWidget::retranslate()
     // also retranslate the items
     for (QTreeWidgetItemIterator it(this); *it; it++)
     {
-        dynamic_cast<QCustomTreeWidgetItem*>(*it)->updateDisplay();
+        static_cast<QCustomTreeWidgetItem*>(*it)->updateDisplay();
     }
 }
 
@@ -820,15 +879,65 @@ void QCustomTreeWidget::stopMusic(Branch *branch)
         Tree &children = branch->tree();
         if (item->type() == Item::tSound)
         {
-            emit fileToStop(dynamic_cast<SoundItem*>(item));
+            emit fileToStop(static_cast<SoundItem*>(item));
         }
         for (Tree::iterator it = children.begin(); it != children.end(); it++)
         {
             Item *childItem = it.branch()->item();
             if (childItem->type() == Item::tSound)
             {
-                emit fileToStop(dynamic_cast<SoundItem*>(childItem));
+                emit fileToStop(static_cast<SoundItem*>(childItem));
+            }
+        }
+    }
+}
+
+void QCustomTreeWidget::deleteNotes(Branch *branch)
+{
+    if (branch)
+    {
+        Item *item = branch->item();
+        Tree &children = branch->tree();
+        if (item->type() == Item::tNote)
+        {
+            emit noteToDelete(static_cast<NoteItem*>(item)->note());
+        }
+        for (Tree::iterator it = children.begin(); it != children.end(); it++)
+        {
+            Item *childItem = it.branch()->item();
+            if (childItem->type() == Item::tNote)
+            {
+                emit noteToDelete(static_cast<NoteItem*>(childItem)->note());
+            }
+        }
+    }
+}
+
+bool QCustomTreeWidget::viewportEvent(QEvent *e)
+{
+    // dynamical tool tip for note items
+    if (e->type() == QEvent::ToolTip)
+    {
+        QHelpEvent *helpEvent = static_cast<QHelpEvent*>(e);
+        // only the first column
+        if (columnAt(helpEvent->x()) == 0)
+        {
+            QCustomTreeWidgetItem *qItem = dynamic_cast<QCustomTreeWidgetItem*>(itemAt(helpEvent->pos()));
+            if (qItem)
+            {
+                Item *item = qItem->branch()->item();
+                if (item->type() == Item::tNote)
+                {
+                    QToolTip::showText(helpEvent->globalPos(), static_cast<NoteItem*>(item)->note()->title().c_str());
+                    return true;
+                }
+                else
+                {
+                    return QTreeWidget::viewportEvent(e);
+                }
             }
         }
+        QToolTip::hideText();
     }
+    return QTreeWidget::viewportEvent(e);
 }
diff --git a/sources/widgets/QCustomTreeWidget.h b/sources/widgets/QCustomTreeWidget.h
index 011ded3..3baac64 100644
--- a/sources/widgets/QCustomTreeWidget.h
+++ b/sources/widgets/QCustomTreeWidget.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2011-2019 Vincent Prat & Simon Nicolas
+* Copyright © 2011-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -138,38 +138,44 @@ class QCustomTreeWidget: public QTreeWidget
          * \brief DoubleClickEvent handler
          * \param e Mouse event
          */
-        void mouseDoubleClickEvent(QMouseEvent *e);
+        void mouseDoubleClickEvent(QMouseEvent *e) override;
         /*!
          * \brief Event raised when a mouse button is pressed
          * \param e Mouse event
          */
-        void mousePressEvent(QMouseEvent *e);
+        void mousePressEvent(QMouseEvent *e) override;
         /*!
          * \brief Event raised when a mouse button is released
          * \param e Mouse event
          */
-        void mouseReleaseEvent(QMouseEvent *e);
+        void mouseReleaseEvent(QMouseEvent *e) override;
         /*!
          * \brief Event raised when a key is released
          * \param e Key event
          */
-        void keyReleaseEvent(QKeyEvent *e);
+        void keyReleaseEvent(QKeyEvent *e) override;
         /*!
          * \brief DropEvent handler
          * \param e Event to handle
          */
-        void dropEvent(QDropEvent *e);
+        void dropEvent(QDropEvent *e) override;
         /*!
          * \brief ChangeEvent handler
          * \param e Event to handle
          */
-        void changeEvent(QEvent *e);
+        void changeEvent(QEvent *e) override;
         /*!
          * \brief Retranslator
          *
          * Retranslates the menu
          */
         void retranslate();
+        /*!
+         * \brief Viewport event handler (used for dynamical tool tips)
+         * \param e Event
+         * \return True if the event is handled
+         */
+        bool viewportEvent(QEvent *e) override;
     protected slots:
         /*!
          * \brief Slot for when an item is expanded
@@ -244,6 +250,11 @@ class QCustomTreeWidget: public QTreeWidget
          * \param branch Branch where the item to stop would be
          */
         void stopMusic(Branch *branch);
+        /*!
+         * \brief Method to delete notes in a given branch
+         * \param branch Branch where the notes to delete would be
+         */
+        void deleteNotes(Branch *branch);
     signals:
         /*!
          * \brief Signal to play a file
@@ -270,6 +281,20 @@ class QCustomTreeWidget: public QTreeWidget
          * \param newItem New sound item
          */
         void fileToChange(const SoundItem *oldItem, const SoundItem *newItem);
+        /*!
+         * \brief Signal to open a note
+         * \param note Note we want to open
+         *
+         * This signal is sent when a note has to be opened
+         */
+        void noteToOpen(Note *note);
+        /*!
+         * \brief Signal to delete a note
+         * \param note Note we want to delete
+         *
+         * This signal is sent when a note has to be deleted
+         */
+        void noteToDelete(Note *note);
 };
 
 #endif
diff --git a/sources/widgets/QCustomTreeWidgetItem.cpp b/sources/widgets/QCustomTreeWidgetItem.cpp
index de02568..3090c6e 100644
--- a/sources/widgets/QCustomTreeWidgetItem.cpp
+++ b/sources/widgets/QCustomTreeWidgetItem.cpp
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2011-2018 Vincent Prat & Simon Nicolas
+* Copyright © 2011-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -52,7 +52,7 @@ void QCustomTreeWidgetItem::updateDisplay()
     Item::Type type = item->type();
     if (Item::is(type, Item::tFile))
     {
-        FileItem *fileItem = dynamic_cast<FileItem*>(item);
+        FileItem *fileItem = static_cast<FileItem*>(item);
         std::string fileName = fileItem->fileName(); 
         if (fileItem->isIncluded())
         {
@@ -66,17 +66,24 @@ void QCustomTreeWidgetItem::updateDisplay()
         switch (type)
         {
             case Item::tSound:  setIcon(0,QIcon(":/data/images/speaker.svg"));
-                                if (dynamic_cast<QCustomTreeWidget*>(treeWidget())->playingMethod() != QCustomTreeWidget::pmNone)
+                                if (static_cast<QCustomTreeWidget*>(treeWidget())->playingMethod() != QCustomTreeWidget::pmNone)
                                 {
                                     setStatusTip(0,QApplication::translate("customTree","Double click to play the file",0));
                                 }
                                 break;
             case Item::tImage:  setIcon(0,QIcon(":/data/images/image.svg"));
-                                setStatusTip(0,QApplication::translate("customTree","Double click to show the file",0));
+                                setStatusTip(0,QApplication::translate("customTree", "Double click to display the image", 0));
                                 break;
             default:    break;
         }
     }
+    else if (item->type() == Item::tNote)
+    {
+        setIcon(0, QIcon(":/data/images/text.svg"));
+        setStatusTip(0, QApplication::translate("customTree", "Double click to display the note", 0));
+        NoteItem *noteItem = static_cast<NoteItem*>(item);
+        setToolTip(0, noteItem->note()->title().c_str());
+    }
     else
     {
         setIcon(0, QIcon());
diff --git a/sources/widgets/QCustomTreeWidgetItem.h b/sources/widgets/QCustomTreeWidgetItem.h
index 01cc531..6e84cf5 100644
--- a/sources/widgets/QCustomTreeWidgetItem.h
+++ b/sources/widgets/QCustomTreeWidgetItem.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2011-2014 Vincent Prat & Simon Nicolas
+* Copyright © 2011-2018 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -33,7 +33,7 @@ class QCustomTreeWidgetItem: public QTreeWidgetItem
         QCustomTreeWidgetItem(QCustomTreeWidget *parent, Branch *branch, QCustomTreeWidgetItem *previous);
         QCustomTreeWidgetItem(QCustomTreeWidgetItem *parent, Branch *branch, QCustomTreeWidgetItem *previous);
         Branch* branch();
-        /*
+        /*!
          * \brief Update of the display (icon, text, tool/status tips)
          */
         void updateDisplay();
diff --git a/sources/windows/AboutDialog.h b/sources/windows/AboutDialog.h
index a28a5cc..d70884b 100644
--- a/sources/windows/AboutDialog.h
+++ b/sources/windows/AboutDialog.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2011-2013 Vincent Prat & Simon Nicolas
+* Copyright © 2011-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -41,7 +41,7 @@ class AboutDialog: public QDialog, private Ui::AboutDialog
          *
          * Updates the translation when changing language
          */
-        void changeEvent(QEvent *e);
+        void changeEvent(QEvent *e) override;
 };
 
 #endif
diff --git a/sources/windows/ChangeCharacterDialog.h b/sources/windows/ChangeCharacterDialog.h
index 3d73809..34ce2c9 100644
--- a/sources/windows/ChangeCharacterDialog.h
+++ b/sources/windows/ChangeCharacterDialog.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2011-2013 Vincent Prat & Simon Nicolas
+* Copyright © 2011-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -65,7 +65,7 @@ class ChangeCharacterDialog: public QDialog, private Ui::changeCharacterDialog
          *
          * Updates the translation when changing language
          */
-        void changeEvent(QEvent *e);
+        void changeEvent(QEvent *e) override;
 };
 
 QString ChangeCharacterDialog::name() const
diff --git a/sources/windows/ChangePropertyDialog.h b/sources/windows/ChangePropertyDialog.h
index 37c66d1..9b23ec7 100644
--- a/sources/windows/ChangePropertyDialog.h
+++ b/sources/windows/ChangePropertyDialog.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2011-2013 Vincent Prat & Simon Nicolas
+* Copyright © 2011-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -59,7 +59,7 @@ class ChangePropertyDialog: public QDialog, private Ui::changePropertyDialog
          *
          * Updates the translation when changing language
          */
-        void changeEvent(QEvent *e);
+        void changeEvent(QEvent *e) override;
 };
 
 #endif
diff --git a/sources/windows/CombatDialog.cpp b/sources/windows/CombatDialog.cpp
index c522330..84024da 100644
--- a/sources/windows/CombatDialog.cpp
+++ b/sources/windows/CombatDialog.cpp
@@ -31,6 +31,7 @@ CombatDialog::CombatDialog(QWidget *parent): QDialog(parent)
 
 void CombatDialog::show(const QStringList &list)
 {
+    iRound = 1;
     iCharacter = 0;
     tableWidget->setRowCount(0);
     tableWidget->setRowCount(list.size());
@@ -52,6 +53,12 @@ void CombatDialog::show(const QStringList &list)
 void CombatDialog::on_pushNext_clicked()
 {
     iCharacter++;
+    if (iCharacter == tableWidget->rowCount())
+    {
+        // new round
+        iRound++;
+        iCharacter = 0;
+    }
     updateDisplay();
 }
 
@@ -72,7 +79,8 @@ void CombatDialog::updateDisplay()
             tableWidget->item(n, 0)->setBackground(QPalette().color(QPalette::Base));
         }
     }
-    label->setText(QApplication::translate("combatDialog", "Current character:", 0) + " <strong>"+tableWidget->verticalHeaderItem(logical)->text()+"</strong>");
+    roundLabel->setText(QApplication::translate("combatDialog", "Round number:", 0) + QString(" <strong>%1</strong>").arg(iRound));
+    characterLabel->setText(QApplication::translate("combatDialog", "Current character:", 0) + " <strong>" + tableWidget->verticalHeaderItem(logical)->text() + "</strong>");
 }
 
 void CombatDialog::onCharacterMoved(int, int oldVisualIndex, int newVisualIndex)
diff --git a/sources/windows/CombatDialog.h b/sources/windows/CombatDialog.h
index 10adb58..3f63c87 100644
--- a/sources/windows/CombatDialog.h
+++ b/sources/windows/CombatDialog.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2013-2017 Vincent Prat & Simon Nicolas
+* Copyright © 2013-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -29,7 +29,9 @@ class CombatDialog: public QDialog, private Ui::combatDialog
 {
     Q_OBJECT
     private:
-        //! Counter
+        //! Round counter
+        int iRound;
+        //! Character counter
         int iCharacter;
         //! Vertical header
         QHeaderView *header;
@@ -40,14 +42,14 @@ class CombatDialog: public QDialog, private Ui::combatDialog
          *
          * Updates the translation when changing language
          */
-        void changeEvent(QEvent *e);
+        void changeEvent(QEvent *e) override;
         /*!
          * \brief CloseEvent handler
          * \param e Event to handle
          *
          * Asks for confirmation before closing the dialog window
          */
-        void closeEvent(QCloseEvent *e);
+        void closeEvent(QCloseEvent *e) override;
     public:
         //! Default constructor
         CombatDialog(QWidget *parent);
diff --git a/sources/windows/CombatDialog.ui b/sources/windows/CombatDialog.ui
index b39528b..1ebf858 100644
--- a/sources/windows/CombatDialog.ui
+++ b/sources/windows/CombatDialog.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>287</width>
-    <height>245</height>
+    <width>274</width>
+    <height>295</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -15,7 +15,14 @@
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
-    <widget class="QLabel" name="label">
+    <widget class="QLabel" name="roundLabel">
+     <property name="text">
+      <string>Round number:</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLabel" name="characterLabel">
      <property name="text">
       <string>Current character:</string>
      </property>
diff --git a/sources/windows/DiceDialog.cpp b/sources/windows/DiceDialog.cpp
index d312c49..85c19ab 100644
--- a/sources/windows/DiceDialog.cpp
+++ b/sources/windows/DiceDialog.cpp
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2013 Vincent Prat & Simon Nicolas
+* Copyright © 2013-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -49,22 +49,74 @@ void DiceDialog::on_pushThrow_clicked()
                     break;
         default:    faces = 100;
     }
-    QString result;
+    // limiting the possible values for counting
+    spinEqual->setMaximum(faces);
+    spinLeast->setMaximum(faces);
+    spinMost->setMaximum(faces);
+
     int nb = spinNumber->value();
+
+    // results
+    vResults.resize(nb);
+    QString result;
+    int sum = 0;
+    int min = faces;
+    int max = 1;
+    int nequal = 0;
+    int nleast = 0;
+    int nmost = 0;
+
     for (int i = 0; i < nb; i++)
     {
-        result += QString("%1").arg(rand() % faces + 1);
+        int res = rand() % faces + 1;
+        vResults[i] = res;
+        result += QString("%1").arg(res);
         if (i+1 < nb)
         {
             result += " ";
         }
+        // computations
+        sum += res;
+        if (res > max)
+        {
+            max = res;
+        }
+        if (res < min)
+        {
+            min = res;
+        }
+        if (res == spinEqual->value())
+        {
+            nequal++;
+        }
+        if (res >= spinLeast->value())
+        {
+            nleast++;
+        }
+        if (res <= spinMost->value())
+        {
+            nmost++;
+        }
     }
-    lineResult->setText(result);
+    textResult->setPlainText(result);
+    lineSum->setText(QString("%1").arg(sum));
+    lineMin->setText(QString("%1").arg(min));
+    lineMax->setText(QString("%1").arg(max));
+    lineEqual->setText(QString("%1").arg(nequal));
+    lineLeast->setText(QString("%1").arg(nleast));
+    lineMost->setText(QString("%1").arg(nmost));
 }
 
 void DiceDialog::on_pushReset_clicked()
 {
-    lineResult->setText(QString());
+    vResults.clear();
+    textResult->clear();
+    lineSum->clear();
+    lineMin->clear();
+    lineMax->clear();
+    lineEqual->clear();
+    lineLeast->clear();
+    lineMost->clear();
 }
 
 void DiceDialog::show()
@@ -80,3 +132,51 @@ void DiceDialog::changeEvent(QEvent *e)
         retranslateUi(this);
     }
 }
+
+void DiceDialog::on_spinEqual_valueChanged(int value)
+{
+    int count = 0;
+    for (std::vector<int>::const_iterator it = vResults.begin(); it != vResults.end(); it++)
+    {
+        if (*it == value)
+        {
+            count++;
+        }
+    }
+    if (vResults.size() > 0)
+    {
+        lineEqual->setText(QString("%1").arg(count));
+    }
+}
+
+void DiceDialog::on_spinLeast_valueChanged(int value)
+{
+    int count = 0;
+    for (std::vector<int>::const_iterator it = vResults.begin(); it != vResults.end(); it++)
+    {
+        if (*it >= value)
+        {
+            count++;
+        }
+    }
+    if (vResults.size() > 0)
+    {
+        lineLeast->setText(QString("%1").arg(count));
+    }
+}
+
+void DiceDialog::on_spinMost_valueChanged(int value)
+{
+    int count = 0;
+    for (std::vector<int>::const_iterator it = vResults.begin(); it != vResults.end(); it++)
+    {
+        if (*it <= value)
+        {
+            count++;
+        }
+    }
+    if (vResults.size() > 0)
+    {
+        lineMost->setText(QString("%1").arg(count));
+    }
+}
diff --git a/sources/windows/DiceDialog.h b/sources/windows/DiceDialog.h
index 00b7f90..d82bdb6 100644
--- a/sources/windows/DiceDialog.h
+++ b/sources/windows/DiceDialog.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2013 Vincent Prat & Simon Nicolas
+* Copyright © 2013-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -20,6 +20,7 @@
 #define HEADER_DICEDIALOG
 
 #include "ui_DiceDialog.h"
+#include <vector>
 
 /*!
  * \brief Dialog window for dice simulation
@@ -52,6 +53,21 @@ class DiceDialog: public QDialog, private Ui::diceDialog
          * Resets the results
          */
         void show();
+        /*!
+         * \brief Slot for when the number of dice equal to a certain number needs to be recomputed
+         * \param value Value to compare to the dice
+         */
+        void on_spinEqual_valueChanged(int value);
+        /*!
+         * \brief Slot for when the number of dice greater or equal to a certain number needs to be recomputed
+         * \param value Value to compare to the dice
+         */
+        void on_spinLeast_valueChanged(int value);
+        /*!
+         * \brief Slot for when the number of dice lower or equal to a certain number needs to be recomputed
+         * \param value Value to compare to the dice
+         */
+        void on_spinMost_valueChanged(int value);
     protected:
         /*!
          * \brief ChangeEvent handler
@@ -59,7 +75,10 @@ class DiceDialog: public QDialog, private Ui::diceDialog
          *
          * Updates the translation when changing language
          */
-        void changeEvent(QEvent *e);
+        void changeEvent(QEvent *e) override;
+    private:
+        //! List of results
+        std::vector<int> vResults;
 };
 
 #endif
diff --git a/sources/windows/DiceDialog.ui b/sources/windows/DiceDialog.ui
index 4ddf4f8..60e4044 100644
--- a/sources/windows/DiceDialog.ui
+++ b/sources/windows/DiceDialog.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>305</width>
-    <height>172</height>
+    <width>274</width>
+    <height>523</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -97,19 +97,128 @@
         <number>1</number>
        </property>
        <property name="maximum">
-        <number>10</number>
+        <number>100</number>
        </property>
       </widget>
      </item>
     </layout>
    </item>
    <item>
-    <widget class="QLineEdit" name="lineResult">
+    <widget class="QPlainTextEdit" name="textResult">
      <property name="readOnly">
       <bool>true</bool>
      </property>
     </widget>
    </item>
+   <item>
+    <layout class="QGridLayout" name="gridLayout">
+     <item row="2" column="2">
+      <widget class="QLineEdit" name="lineMax">
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="0" colspan="2">
+      <widget class="QLabel" name="label_3">
+       <property name="text">
+        <string>Sum:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="2">
+      <widget class="QLineEdit" name="lineSum">
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="1">
+      <widget class="QSpinBox" name="spinEqual">
+       <property name="minimum">
+        <number>1</number>
+       </property>
+      </widget>
+     </item>
+     <item row="4" column="1">
+      <widget class="QSpinBox" name="spinLeast">
+       <property name="minimum">
+        <number>1</number>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="2">
+      <widget class="QLineEdit" name="lineEqual">
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="2">
+      <widget class="QLineEdit" name="lineMin">
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="0">
+      <widget class="QLabel" name="label_6">
+       <property name="text">
+        <string>Equal to</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0" colspan="2">
+      <widget class="QLabel" name="label_4">
+       <property name="text">
+        <string>Minimum:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="0" colspan="2">
+      <widget class="QLabel" name="label_5">
+       <property name="text">
+        <string>Maximum:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="4" column="2">
+      <widget class="QLineEdit" name="lineLeast">
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="4" column="0">
+      <widget class="QLabel" name="label_7">
+       <property name="text">
+        <string>At least</string>
+       </property>
+      </widget>
+     </item>
+     <item row="5" column="0">
+      <widget class="QLabel" name="label_8">
+       <property name="text">
+        <string>At most</string>
+       </property>
+      </widget>
+     </item>
+     <item row="5" column="1">
+      <widget class="QSpinBox" name="spinMost">
+       <property name="minimum">
+        <number>1</number>
+       </property>
+      </widget>
+     </item>
+     <item row="5" column="2">
+      <widget class="QLineEdit" name="lineMost">
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
diff --git a/sources/windows/ItemDialog.cpp b/sources/windows/ItemDialog.cpp
index 2194d14..edf3776 100644
--- a/sources/windows/ItemDialog.cpp
+++ b/sources/windows/ItemDialog.cpp
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2011-2021 Vincent Prat & Simon Nicolas
+* Copyright © 2011-2022 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -41,17 +41,14 @@ Item::State ItemDialog::state() const
         return Item::sSuccess;
 }
 
-QString ItemDialog::text() const
-{
-    return editItem->text();
-}
-
 Item::Type ItemDialog::type() const
 {
     if (radioSound->isChecked())
         return Item::tSound;
     else if (radioImage->isChecked())
         return Item::tImage;
+    else if (radioNote->isChecked())
+        return Item::tNote;
     else
         return Item::tBasic;
 }
@@ -72,14 +69,14 @@ void ItemDialog::on_pushChild_clicked()
 {
     if (editItem->text()!="")
     {
-        if (radioBasic->isChecked() || editFile->text()!="")
+        if (radioBasic->isChecked() || radioNote->isChecked() || editFile->text() != "")
         {
             rRes = rChild;
             accept();
         }
         else
         {
-        QMessageBox::critical(this,QApplication::translate("itemDialog","Incomplete data",0),QApplication::translate("itemDialog","You must select a file before validating.",0));
+            QMessageBox::critical(this,QApplication::translate("itemDialog","Incomplete data",0),QApplication::translate("itemDialog","You must select a file before validating.",0));
         }
     }
     else
@@ -92,7 +89,7 @@ void ItemDialog::on_pushBrother_clicked()
 {
     if (editItem->text()!="")
     {
-        if (radioBasic->isChecked() || editFile->text()!="")
+        if (radioBasic->isChecked() || radioNote->isChecked() || editFile->text()!="")
         {
             rRes = rBrother;
             accept();
@@ -108,11 +105,6 @@ void ItemDialog::on_pushBrother_clicked()
     }
 }
 
-ItemDialog::Result ItemDialog::selectionResult() const
-{
-    return rRes;
-}
-
 void ItemDialog::on_radioBasic_clicked()
 {
     toolBrowse->setEnabled(false);
@@ -130,6 +122,11 @@ void ItemDialog::on_radioImage_clicked()
     editFile->setText("");
 }
 
+void ItemDialog::on_radioNote_clicked()
+{
+    toolBrowse->setEnabled(false);
+}
+
 void ItemDialog::on_toolBrowse_clicked()
 {
     switch (type())
@@ -166,9 +163,9 @@ int ItemDialog::exec(Item *item)
         content = item->content().c_str();
         itemType = item->type();
         itemState = item->state();
-        if (itemType != Item::tBasic)
+        if (Item::is(itemType, Item::tFile))
         {
-            file = dynamic_cast<FileItem*>(item)->fileName().c_str();
+            file = static_cast<FileItem*>(item)->fileName().c_str();
         }
     }
     else
@@ -190,8 +187,9 @@ int ItemDialog::exec(Item *item)
     radioBasic->setChecked(itemType == Item::tBasic);
     radioSound->setChecked(itemType == Item::tSound);
     radioImage->setChecked(itemType == Item::tImage);
+    radioNote->setChecked(itemType == Item::tNote);
     // everuthing else
-    toolBrowse->setEnabled(itemType != Item::tBasic);
+    toolBrowse->setEnabled(itemType != Item::tBasic && itemType != Item::tNote);
 
     editItem->setText(content);
     editItem->setFocus();
diff --git a/sources/windows/ItemDialog.h b/sources/windows/ItemDialog.h
index 5651c71..74eb6ad 100644
--- a/sources/windows/ItemDialog.h
+++ b/sources/windows/ItemDialog.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2011-2019 Vincent Prat & Simon Nicolas
+* Copyright © 2011-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -40,7 +40,15 @@ class ItemDialog: public QDialog, private Ui::itemDialog
         ItemDialog(QWidget *parent=0);
         // accessors
         Item::State state() const;
-        QString text() const;
+        /*!
+         * \brief Getter for the text of the item
+         * \return Text of the item
+         */
+        inline QString text() const;
+        /*!
+         * \brief Getter for the type of the item
+         * \return Type of the item
+         */
         Item::Type type() const;
         /*!
          * \brief Getter for the name of the file
@@ -48,9 +56,23 @@ class ItemDialog: public QDialog, private Ui::itemDialog
          * If the file is within the current directory, returns the relative path
          */
         QString fileName() const;
-        Result selectionResult() const;
+        /*!
+         * \brief Getter for the result of the selection
+         * \return Result of the selection
+         */
+        inline Result selectionResult() const;
     public slots:
+        /*!
+         * \brief Slot for the "Child" push button
+         *
+         * Creates a new item as a child of the current item
+         */
         void on_pushChild_clicked();
+        /*!
+         * \brief Slot for the "Brother" push button
+         *
+         * Creates a new item at the same level as the current item
+         */
         void on_pushBrother_clicked();
         /*!
          * \brief Slot for the "Basic" radio button
@@ -64,6 +86,12 @@ class ItemDialog: public QDialog, private Ui::itemDialog
          * Sets the type of the item to tSound
          */
         void on_radioSound_clicked();
+        /*!
+         * \brief Slot for the "Note" radio item
+         *
+         * Sets the type of the item to tNote
+         */
+        void on_radioNote_clicked();
         /*!
          * \brief Slot for the "Browse" tool button
          *
@@ -92,7 +120,7 @@ class ItemDialog: public QDialog, private Ui::itemDialog
          *
          * Updates the translation when changing language
          */
-        void changeEvent(QEvent *e);
+        void changeEvent(QEvent *e) override;
     private:
         //! Modal result
         Result rRes;
@@ -100,4 +128,14 @@ class ItemDialog: public QDialog, private Ui::itemDialog
         QFileDialog *audioBrowser;
 };
 
+QString ItemDialog::text() const
+{
+    return editItem->text();
+}
+
+ItemDialog::Result ItemDialog::selectionResult() const
+{
+    return rRes;
+}
+
 #endif
diff --git a/sources/windows/ItemDialog.ui b/sources/windows/ItemDialog.ui
index 6ef0f3f..e258ba6 100644
--- a/sources/windows/ItemDialog.ui
+++ b/sources/windows/ItemDialog.ui
@@ -10,7 +10,7 @@
     <x>0</x>
     <y>0</y>
     <width>325</width>
-    <height>483</height>
+    <height>487</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -111,6 +111,17 @@
         </property>
        </widget>
       </item>
+      <item>
+       <widget class="QRadioButton" name="radioNote">
+        <property name="text">
+         <string>N&amp;ote</string>
+        </property>
+        <property name="icon">
+         <iconset resource="../../ressource.qrc">
+          <normaloff>:/data/images/text.svg</normaloff>:/data/images/text.svg</iconset>
+        </property>
+       </widget>
+      </item>
       <item>
        <widget class="QRadioButton" name="radioSound">
         <property name="text">
diff --git a/sources/windows/MainWindow.cpp b/sources/windows/MainWindow.cpp
index 9921f6d..113b0de 100644
--- a/sources/windows/MainWindow.cpp
+++ b/sources/windows/MainWindow.cpp
@@ -31,7 +31,7 @@
 #include "MetadataModification.h"
 #include <Poco/Exception.h>
 
-MainWindow::MainWindow(const QString &install_dir): QMainWindow(), musicPlayer(new QMediaPlayer(this)), soundPlayer(new QMediaPlayer(this)), pAboutDial(new AboutDialog(this)), pDiceDialog(new DiceDialog(this)), pCombatDialog(new CombatDialog(this)), smRecent(new QSignalMapper(this)), siCurrentMusic(0), tApplication(new QTranslator(this)), tSystem(new QTranslator(this)), sInstall(install_dir), smLanguage(new QSignalMapper(this)), pMetadataDialog(new MetadataDialog(this)), pItemDialog(new ItemDialog(this))
+MainWindow::MainWindow(const QString &install_dir): QMainWindow(), musicPlayer(new QMediaPlayer(this)), soundPlayer(new QMediaPlayer(this)), pAboutDial(new AboutDialog(this)), pDiceDialog(new DiceDialog(this)), pCombatDialog(new CombatDialog(this)), smRecent(new QSignalMapper(this)), siCurrentMusic(0), tApplication(new QTranslator(this)), tSystem(new QTranslator(this)), sInstall(install_dir), smLanguage(new QSignalMapper(this)), pMetadataDialog(new MetadataDialog(this)), pItemDialog(new ItemDialog(this)), pReleaseNotesDialog(new ReleaseNotesDialog(this, install_dir))
 {
     pSelectCharacterDialog = new SelectCharacterDialog(this, pCombatDialog);
     setupUi(this);
@@ -104,11 +104,22 @@ MainWindow::MainWindow(const QString &install_dir): QMainWindow(), musicPlayer(n
     treeMusic->installEventFilter(this);
     connect(treeFX, SIGNAL(modificationDone(Modification*)), this, SLOT(registerModification(Modification*)));
     treeFX->installEventFilter(this);
-    connect(textNotes, SIGNAL(modificationDone(Modification*)), this, SLOT(registerModification(Modification*)));
-    connect(textNotes, SIGNAL(unregistered()), this, SLOT(updateUndoRedo()));
-    textNotes->installEventFilter(this);
+    connect(tabNotes, SIGNAL(noteOpened(QCustomTextEdit*)), this, SLOT(connectNote(QCustomTextEdit*)));
+    connect(tabNotes, SIGNAL(modificationDone(Modification*)), this, SLOT(registerModification(Modification*)));
+    tabNotes->installEventFilter(this);
     connect(tableStats, SIGNAL(modificationDone(Modification*)), this, SLOT(registerModification(Modification*)));
     tableStats->installEventFilter(this);
+    // notes
+    connect(treePlot, SIGNAL(noteToOpen(Note*)), tabNotes, SLOT(openNote(Note*)));
+    connect(treeHistory, SIGNAL(noteToOpen(Note*)), tabNotes, SLOT(openNote(Note*)));
+    connect(treeMusic, SIGNAL(noteToOpen(Note*)), tabNotes, SLOT(openNote(Note*)));
+    connect(treeFX, SIGNAL(noteToOpen(Note*)), tabNotes, SLOT(openNote(Note*)));
+    connect(treePlot, SIGNAL(noteToDelete(Note*)), tabNotes, SLOT(deleteNote(Note*)));
+    connect(treeHistory, SIGNAL(noteToDelete(Note*)), tabNotes, SLOT(deleteNote(Note*)));
+    connect(treeMusic, SIGNAL(noteToDelete(Note*)), tabNotes, SLOT(deleteNote(Note*)));
+    connect(treeFX, SIGNAL(noteToDelete(Note*)), tabNotes, SLOT(deleteNote(Note*)));
+    connect(tableStats, SIGNAL(noteToOpen(Note*)), tabNotes, SLOT(openNote(Note*)));
+    connect(tableStats, SIGNAL(noteToDelete(Note*)), tabNotes, SLOT(deleteNote(Note*)));
 
     // Item dialog
     treePlot->setItemDialogWindow(pItemDialog);
@@ -362,7 +373,7 @@ void MainWindow::on_action_Save_triggered()
 
 bool MainWindow::on_actionS_ave_as_triggered()
 {
-    QString filters(QApplication::translate("mainWindow","GM-Assistant files (1.2) (*.gms)",0));
+    QString filters(QApplication::translate("mainWindow","GM-Assistant files (*.gms)",0));
     if (!sGame.configuration().isArchived())
     {
         filters += QApplication::translate("mainWindow",";;GM-Assistant files (1.1) (*.gma);;GM-Assistant files (1.0) (*.xml)",0);
@@ -436,8 +447,9 @@ void MainWindow::updateDisplay()
         case Scenario::uiNoMusic: on_actionNoMusic_triggered();
                                 break;
     }
+    tabNotes->clear();
+    tabNotes->openNote(&sGame.mainNote());
     treePlot->setTree(&sGame.plot());
-    textNotes->setNotes(&sGame.notes());
     treeHistory->setTree(&sGame.history());
     treeMusic->setTree(&sGame.music());
     treeFX->setTree(&sGame.effects());
@@ -470,10 +482,10 @@ void MainWindow::on_buttonMusic_clicked()
                 QTreeWidgetItem *qItem = treeMusic->currentItem();
                 if (qItem)
                 {
-                    Item *item = dynamic_cast<QCustomTreeWidgetItem*>(qItem)->branch()->item();
+                    Item *item = static_cast<QCustomTreeWidgetItem*>(qItem)->branch()->item();
                     if (item->type()==Item::tSound)
                     {
-                        SoundItem *sItem = dynamic_cast<SoundItem*>(item);
+                        SoundItem *sItem = static_cast<SoundItem*>(item);
                         playMusic(sItem);
                     }
                 }
@@ -678,7 +690,7 @@ void MainWindow::updateModification(Modification *modification, bool undo)
     {
         case Modification::tTree:   
             {
-                TreeModification* treeModif = dynamic_cast<TreeModification*>(modification);
+                TreeModification* treeModif = static_cast<TreeModification*>(modification);
                 Tree *adr = &treeModif->tree();
                 if (adr == &sGame.plot())
                 {
@@ -698,9 +710,9 @@ void MainWindow::updateModification(Modification *modification, bool undo)
                 }
                 break;
             }
-        case Modification::tNote:   textNotes->updateModification(dynamic_cast<NoteModification*>(modification), undo);
+        case Modification::tNote:   tabNotes->updateModification(static_cast<NoteModification*>(modification), undo);
                                     break;
-        case Modification::tCharacter:  tableStats->updateModification(dynamic_cast<CharacterModification*>(modification), undo);
+        case Modification::tCharacter:  tableStats->updateModification(static_cast<CharacterModification*>(modification), undo);
                                         break;
         default : break;
     }
@@ -722,7 +734,7 @@ void MainWindow::updateUndoRedo()
 {
     action_Undo->setEnabled(mqQueue.undoable());
     action_Redo->setEnabled(mqQueue.redoable());
-    bool modified = !mqQueue.isUpToDate() || textNotes->unregisteredModification();
+    bool modified = isModified();
     action_Save->setEnabled(modified);
 
     QString windowTitle("GM-Assistant - ");
@@ -757,16 +769,17 @@ bool MainWindow::eventFilter(QObject *source, QEvent *e)
 {
     if (e->type() == QEvent::KeyPress)
     {
-        QKeyEvent *event = dynamic_cast<QKeyEvent*>(e);
+        QKeyEvent *event = static_cast<QKeyEvent*>(e);
         Qt::KeyboardModifiers modifiers = event->modifiers();
         switch (event->key())
         {
             case Qt::Key_Z: // undo - redo
                             if (modifiers == Qt::ControlModifier)
                             {
-                                if (source == textNotes)
+                                QCustomTextEdit *edit = dynamic_cast<QCustomTextEdit*>(source);
+                                if (edit)
                                 {
-                                    textNotes->checkModification();
+                                    edit->checkModification();
                                 }
                                 if (mqQueue.undoable())
                                 {
@@ -776,9 +789,10 @@ bool MainWindow::eventFilter(QObject *source, QEvent *e)
                             }
                             else if (modifiers == (Qt::ControlModifier | Qt::ShiftModifier))
                             {
-                                if (source == textNotes)
+                                QCustomTextEdit *edit = dynamic_cast<QCustomTextEdit*>(source);
+                                if (edit)
                                 {
-                                    textNotes->checkModification();
+                                    edit->checkModification();
                                 }
                                 if (mqQueue.redoable())
                                 {
@@ -787,19 +801,31 @@ bool MainWindow::eventFilter(QObject *source, QEvent *e)
                                 return true;
                             }
                             break;
-            case Qt::Key_V: if (source == textNotes && modifiers == Qt::ControlModifier)
+            case Qt::Key_V: if (modifiers == Qt::ControlModifier)
                             {
-                                textNotes->forcePaste();
+                                QCustomTextEdit *edit = dynamic_cast<QCustomTextEdit*>(source);
+                                if (edit)
+                                {
+                                    edit->forcePaste();
+                                }
                             }
                             break;
-            case Qt::Key_X: if (source == textNotes && modifiers == Qt::ControlModifier)
+            case Qt::Key_X: if (modifiers == Qt::ControlModifier)
                             {
-                                textNotes->forceCut();
+                                QCustomTextEdit *edit = dynamic_cast<QCustomTextEdit*>(source);
+                                if (edit)
+                                {
+                                    edit->forceCut();
+                                }
                             }
                             break;
-            default:    if (source == textNotes && modifiers & Qt::ControlModifier)
+            default:    if (modifiers & Qt::ControlModifier)
                         {
-                            textNotes->checkModification();
+                            QCustomTextEdit *edit = dynamic_cast<QCustomTextEdit*>(source);
+                            if (edit)
+                            {
+                                edit->checkModification();
+                            }
                         }
                         break;
         }
@@ -809,17 +835,18 @@ bool MainWindow::eventFilter(QObject *source, QEvent *e)
 
 bool MainWindow::canClose()
 {
-    textNotes->clearFocus();
+    tabNotes->clearFocus();
     if (pCombatDialog->isVisible())
     {
-        // if the combat manager is opened, we try to close it
-        if (!pCombatDialog->close())
+        // if the combat manager is opened
+        switch (QMessageBox::question(this, QApplication::translate("mainWindow", "Confirmation", 0), QApplication::translate("mainWindow", "A combat is ongoing. Would you like to save its status before closing?", 0), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel))
         {
-            // if it is not closed, we cannot close the game
-            return false;
+            case QMessageBox::Save: save();
+                                    return true;
+            case QMessageBox::Cancel:   return false;
         }
     }
-    if (mqQueue.isUpToDate())
+    if (!isModified())
     {
         // no need for confirmation
         return true;
@@ -956,6 +983,12 @@ void MainWindow::onMusicStateChanged(QMediaPlayer::State state)
     }
 }
 
+void MainWindow::connectNote(QCustomTextEdit *note)
+{
+    connect(note, SIGNAL(modificationDone(Modification*)), this, SLOT(registerModification(Modification*)));
+    connect(note, SIGNAL(unregistered()), this, SLOT(updateUndoRedo()));
+}
+
 void MainWindow::onMusicPositionChanged(qint64 position)
 {
     sliderMusic->setValue(position);
@@ -972,3 +1005,8 @@ void MainWindow::on_sliderMusic_sliderMoved(int position)
 {
     musicPlayer->setPosition(position);
 }
+
+void MainWindow::on_action_Release_notes_triggered()
+{
+    pReleaseNotesDialog->exec();
+}
diff --git a/sources/windows/MainWindow.h b/sources/windows/MainWindow.h
index a9947d6..a9750c4 100644
--- a/sources/windows/MainWindow.h
+++ b/sources/windows/MainWindow.h
@@ -30,6 +30,7 @@
 #include "ItemDialog.h"
 #include "MetadataDialog.h"
 #include <QtMultimedia/QMediaPlayer>
+#include "ReleaseNotesDialog.h"
 
 // number of recently opened games stored
 #define RECENT_NUMBER   5
@@ -88,13 +89,22 @@ class MainWindow: public QMainWindow, private Ui::mainWindow
         Scenario sGame;
         //! Item editor
         ItemDialog *pItemDialog;
+        //! Release notes displayer
+        ReleaseNotesDialog *pReleaseNotesDialog;
         /*!
-         * \brief Game saver
+         * \brief Game save
          * \param askForUpdate Indicates if the user should be asked to update an outdated game
          *
          * Saves the game
          */
         void save(bool askForUpdate = true);
+        /*!
+         * \brief Modification test
+         * \return True if there are modifications to save
+         *
+         * Tests if the game has been modified since the last save
+         */
+        inline bool isModified() const;
     protected:
         // overriden methods
         /*!
@@ -103,7 +113,7 @@ class MainWindow: public QMainWindow, private Ui::mainWindow
          *
          * Stores the old size for unmaximizing just after startup
          */
-        void resizeEvent(QResizeEvent *e);
+        void resizeEvent(QResizeEvent *e) override;
         /*!
          * \brief Event filter
          * \param source Source of the event
@@ -111,21 +121,21 @@ class MainWindow: public QMainWindow, private Ui::mainWindow
          *
          * Intercepts locally handled events related to global shortcuts
          */
-        bool eventFilter(QObject *source, QEvent *e);
+        bool eventFilter(QObject *source, QEvent *e) override;
         /*!
          * \brief CloseEvent handler
          * \param e Event to handle
          *
          * Checks unsaved modifications before closing
          */
-        void closeEvent(QCloseEvent *e);
+        void closeEvent(QCloseEvent *e) override;
         /*!
          * \brief ChangeEvent handler
          * \param e Event to handle
          *
          * Updates the translation when changing language
          */
-        void changeEvent(QEvent *e);
+        void changeEvent(QEvent *e) override;
     public:
         /*!
          * \brief Constructor of the main window
@@ -381,6 +391,22 @@ class MainWindow: public QMainWindow, private Ui::mainWindow
          * \param position New position
          */
         void on_sliderMusic_sliderMoved(int position);
+        /*!
+         * \brief Slot used when a note is opened
+         * \param note Editor for the note
+         */
+        void connectNote(QCustomTextEdit *note);
+        /*!
+         * \brief Slot for the Release notes menu item
+         *
+         * Displays the release notes
+         */
+        void on_action_Release_notes_triggered();
 };
 
+bool MainWindow::isModified() const
+{
+    return !mqQueue.isUpToDate() || tabNotes->unregisteredModification();
+}
+
 #endif
diff --git a/sources/windows/MainWindow.ui b/sources/windows/MainWindow.ui
index 9c5f78a..1bbe167 100644
--- a/sources/windows/MainWindow.ui
+++ b/sources/windows/MainWindow.ui
@@ -112,16 +112,29 @@
         </property>
         <layout class="QVBoxLayout" name="verticalLayout4">
          <item>
-          <widget class="QCustomTextEdit" name="textNotes">
-           <property name="contextMenuPolicy">
-            <enum>Qt::NoContextMenu</enum>
+          <widget class="QCustomTabWidget" name="tabNotes">
+           <property name="currentIndex">
+            <number>0</number>
            </property>
-           <property name="undoRedoEnabled">
-            <bool>false</bool>
+           <property name="elideMode">
+            <enum>Qt::ElideRight</enum>
            </property>
-           <property name="acceptRichText">
+           <property name="tabsClosable">
+            <bool>true</bool>
+           </property>
+           <property name="movable">
             <bool>false</bool>
            </property>
+           <widget class="QWidget" name="tab">
+            <attribute name="title">
+             <string notr="true">Tab 1</string>
+            </attribute>
+           </widget>
+           <widget class="QWidget" name="tab_2">
+            <attribute name="title">
+             <string notr="true">Tab 2</string>
+            </attribute>
+           </widget>
           </widget>
          </item>
         </layout>
@@ -327,6 +340,8 @@
     <property name="title">
      <string>&amp;Help</string>
     </property>
+    <addaction name="action_Release_notes"/>
+    <addaction name="separator"/>
     <addaction name="actionAbout"/>
     <addaction name="actionAbout_Qt"/>
    </widget>
@@ -605,6 +620,14 @@
     <string>Display information about Qt</string>
    </property>
   </action>
+  <action name="action_Release_notes">
+   <property name="text">
+    <string>&amp;Release notes</string>
+   </property>
+   <property name="statusTip">
+    <string>Display the release notes</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>
@@ -618,9 +641,10 @@
    <header>QCustomTableWidget.h</header>
   </customwidget>
   <customwidget>
-   <class>QCustomTextEdit</class>
-   <extends>QTextEdit</extends>
-   <header>QCustomTextEdit.h</header>
+   <class>QCustomTabWidget</class>
+   <extends>QTabWidget</extends>
+   <header>QCustomTabWidget.h</header>
+   <container>1</container>
   </customwidget>
  </customwidgets>
  <resources>
diff --git a/sources/windows/MetadataDialog.h b/sources/windows/MetadataDialog.h
index 1a1c204..686a6b3 100644
--- a/sources/windows/MetadataDialog.h
+++ b/sources/windows/MetadataDialog.h
@@ -1,5 +1,5 @@
 /*************************************************************************
-* Copyright © 2013 Vincent Prat & Simon Nicolas
+* Copyright © 2013-2020 Vincent Prat & Simon Nicolas
 *
 * 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
@@ -37,7 +37,7 @@ class MetadataDialog: public QDialog, private Ui::metadataDialog
          *
          * Updates the translation when changing language
          */
-        void changeEvent(QEvent *e);
+        void changeEvent(QEvent *e) override;
     public:
         /*!
          * \brief Constructor
@@ -55,7 +55,7 @@ class MetadataDialog: public QDialog, private Ui::metadataDialog
          *
          * Modifies the underlying metadata
          */
-        void accept();
+        void accept() override;
         /*!
          * \brief Getter for the metadata
          * \return Metadata
diff --git a/sources/windows/ReleaseNotesDialog.cpp b/sources/windows/ReleaseNotesDialog.cpp
new file mode 100644
index 0000000..79468fb
--- /dev/null
+++ b/sources/windows/ReleaseNotesDialog.cpp
@@ -0,0 +1,53 @@
+/*************************************************************************
+* Copyright © 2020 Vincent Prat & Simon Nicolas
+*
+* 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, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*************************************************************************/
+
+#include "ReleaseNotesDialog.h"
+#include <Poco/FileStream.h>
+
+using namespace std;
+
+ReleaseNotesDialog::ReleaseNotesDialog(QWidget *parent, const QString &install_dir): QDialog(parent)
+{
+    setupUi(this);
+
+    // loading the file
+    QString fileName(install_dir + "CHANGELOG");
+    string line;
+    string text;
+    try
+    {
+        Poco::FileInputStream ibuf(fileName.toStdString());
+        while (getline(ibuf, line))
+        {
+            text += line + "\n";
+        }
+        textEdit->setText(text.c_str());
+    }
+    catch (exception &e)
+    {
+        textEdit->setText(e.what());
+    }
+}
+
+void ReleaseNotesDialog::changeEvent(QEvent *e)
+{
+    if (e->type() == QEvent::LanguageChange)
+    {
+        retranslateUi(this);
+    }
+}
diff --git a/sources/windows/ReleaseNotesDialog.h b/sources/windows/ReleaseNotesDialog.h
new file mode 100644
index 0000000..c264d0f
--- /dev/null
+++ b/sources/windows/ReleaseNotesDialog.h
@@ -0,0 +1,47 @@
+/*************************************************************************
+* Copyright © 2020 Vincent Prat & Simon Nicolas
+*
+* 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, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*************************************************************************/
+
+#ifndef HEADER_RELEASENOTESDIALOG
+#define HEADER_RELEASENOTESDIALOG
+
+#include "ui_ReleaseNotesDialog.h"
+
+/*!
+ * \brief Dialog window for release notes
+ */
+class ReleaseNotesDialog: public QDialog, private Ui::releaseNotesDialog
+{
+    Q_OBJECT
+    public:
+        /*! 
+         * \brief Default constructor
+         * \param parent Parent widget
+         * \param instal_dir Installation directory
+         */
+        ReleaseNotesDialog(QWidget *parent, const QString &install_dir);
+    protected:
+        /*!
+         * \brief ChangeEvent handler
+         * \param e Event to handle
+         *
+         * Updates the translation when changing language
+         */
+        void changeEvent(QEvent *e) override;
+};
+
+#endif
diff --git a/sources/windows/ReleaseNotesDialog.ui b/sources/windows/ReleaseNotesDialog.ui
new file mode 100644
index 0000000..c607e4d
--- /dev/null
+++ b/sources/windows/ReleaseNotesDialog.ui
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>releaseNotesDialog</class>
+ <widget class="QDialog" name="releaseNotesDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>822</width>
+    <height>505</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Release notes</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QTextEdit" name="textEdit">
+     <property name="readOnly">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Close</set>
+     </property>
+     <property name="centerButtons">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>releaseNotesDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>releaseNotesDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/sources/windows/RenameNoteDialog.cpp b/sources/windows/RenameNoteDialog.cpp
new file mode 100644
index 0000000..ed6d5f7
--- /dev/null
+++ b/sources/windows/RenameNoteDialog.cpp
@@ -0,0 +1,58 @@
+/*************************************************************************
+* Copyright © 2019 Vincent Prat & Simon Nicolas
+*
+* 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, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*************************************************************************/
+
+#include "RenameNoteDialog.h"
+#include <QMessageBox>
+#include <QFileDialog>
+
+RenameNoteDialog::RenameNoteDialog(QWidget *parent): QDialog(parent)
+{
+    setupUi(this);
+}
+
+QString RenameNoteDialog::text() const
+{
+    return editName->text();
+}
+
+void RenameNoteDialog::on_pushEdit_clicked()
+{
+    if (editName->text()!="")
+    {
+        accept();
+    }
+    else
+    {
+        QMessageBox::critical(this,QApplication::translate("renameNoteDialog","Incomplete data",0),QApplication::translate("renameNoteDialog","You must fill the title before validating.",0));
+    }
+}
+
+int RenameNoteDialog::exec(QString text)
+{
+    editName->setText(text);
+    editName->setFocus();
+    return QDialog::exec();
+}
+
+void RenameNoteDialog::changeEvent(QEvent *e)
+{
+    if (e->type() == QEvent::LanguageChange)
+    {
+        retranslateUi(this);
+    }
+}
diff --git a/sources/windows/RenameNoteDialog.h b/sources/windows/RenameNoteDialog.h
new file mode 100644
index 0000000..00e2713
--- /dev/null
+++ b/sources/windows/RenameNoteDialog.h
@@ -0,0 +1,65 @@
+/*************************************************************************
+* Copyright © 2019-2020 Vincent Prat & Simon Nicolas
+*
+* 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, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*************************************************************************/
+
+#ifndef HEADER_RENAMENOTEDIALOG
+#define HEADER_RENAMENOTEDIALOG
+
+#include "ui_RenameNoteDialog.h"
+
+/*!
+ * \brief Dialog window for notes
+ */
+class RenameNoteDialog: public QDialog, private Ui::renameNoteDialog
+{
+    Q_OBJECT
+
+    public:
+        /*!
+         * \brief Constructor
+         * \param parent Parent widget
+         */
+        RenameNoteDialog(QWidget *parent=0);
+        /*!
+         * \brief Getter for the text
+         * \return Text of the QLineEdit
+         */
+        QString text() const;
+    public slots:
+        /*!
+         * \brief Slot for when the button is pressed
+         */ 
+        void on_pushEdit_clicked();
+        /*!
+         * \brief Overriden "exec" slot
+         * \param text Pre-filled text
+         * \return Result code
+         *
+         * Resets the interface and shows the window
+         */
+        int exec(QString text="");
+    protected:
+        /*!
+         * \brief ChangeEvent handler
+         * \param e Event to handle
+         *
+         * Updates the translation when changing language
+         */
+        void changeEvent(QEvent *e) override;
+};
+
+#endif
diff --git a/sources/windows/RenameNoteDialog.ui b/sources/windows/RenameNoteDialog.ui
new file mode 100644
index 0000000..d19b84d
--- /dev/null
+++ b/sources/windows/RenameNoteDialog.ui
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>renameNoteDialog</class>
+ <widget class="QDialog" name="renameNoteDialog">
+  <property name="windowModality">
+   <enum>Qt::ApplicationModal</enum>
+  </property>
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>217</width>
+    <height>118</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>New title</string>
+  </property>
+  <property name="modal">
+   <bool>true</bool>
+  </property>
+  <layout class="QVBoxLayout" name="_2">
+   <property name="sizeConstraint">
+    <enum>QLayout::SetFixedSize</enum>
+   </property>
+   <item>
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Title of the note:</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLineEdit" name="editName"/>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QPushButton" name="pushEdit">
+       <property name="text">
+        <string>&amp;Validate</string>
+       </property>
+       <property name="icon">
+        <iconset resource="../../ressource.qrc">
+         <normaloff>:/data/images/check.svg</normaloff>:/data/images/check.svg</iconset>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="pushCancel">
+       <property name="text">
+        <string>&amp;Cancel</string>
+       </property>
+       <property name="icon">
+        <iconset resource="../../ressource.qrc">
+         <normaloff>:/data/images/stop.svg</normaloff>:/data/images/stop.svg</iconset>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../../ressource.qrc"/>
+ </resources>
+ <connections>
+  <connection>
+   <sender>pushCancel</sender>
+   <signal>clicked()</signal>
+   <receiver>renameNoteDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>124</x>
+     <y>96</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>192</x>
+     <y>74</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/sources/windows/SelectCharacterDialog.cpp b/sources/windows/SelectCharacterDialog.cpp
index 44c1e75..decae8c 100644
--- a/sources/windows/SelectCharacterDialog.cpp
+++ b/sources/windows/SelectCharacterDialog.cpp
@@ -44,7 +44,7 @@ void SelectCharacterDialog::show(const CharacterList &list)
     listAll->clear();
     for (CharacterList::const_iterator it = list.begin(); it != list.end(); it++)
     {
-        listAll->addItem((*it).name().c_str());
+        listAll->addItem((*it)->name().c_str());
     }
     listInvolved->clear();
     QDialog::show();
diff --git a/sources/windows/SelectCharacterDialog.h b/sources/windows/SelectCharacterDialog.h
index aa17429..f1a2e03 100644
--- a/sources/windows/SelectCharacterDialog.h
+++ b/sources/windows/SelectCharacterDialog.h
@@ -39,7 +39,7 @@ class SelectCharacterDialog: public QDialog, private Ui::selectCharacterDialog
          *
          * Updates the translation when changing language
          */
-        void changeEvent(QEvent *e);
+        void changeEvent(QEvent *e) override;
     public:
         /*!
          * \brief Default constructor
@@ -79,8 +79,8 @@ class SelectCharacterDialog: public QDialog, private Ui::selectCharacterDialog
          * Put a character a lot lower
          */
         void on_pushDown_clicked();
-        // Overriden slot
-        void accept();
+        //! Slot called when the modifications are accepted
+        void accept() override;
         /*!
          * \brief Slot for double-clicking an item in the character list
          *
diff --git a/translations/gmassistant_fr.ts b/translations/gmassistant_fr.ts
index e52ce8b..99893c7 100644
--- a/translations/gmassistant_fr.ts
+++ b/translations/gmassistant_fr.ts
@@ -144,212 +144,246 @@
     </message>
     <message>
         <location filename="../sources/windows/CombatDialog.ui" line="20"/>
-        <location filename="../sources/windows/CombatDialog.cpp" line="75"/>
+        <location filename="../sources/windows/CombatDialog.cpp" line="71"/>
         <source>Current character:</source>
         <translation>Personnage actuel :</translation>
     </message>
     <message>
-        <location filename="../sources/windows/CombatDialog.cpp" line="107"/>
-        <location filename="../sources/windows/CombatDialog.cpp" line="139"/>
+        <location filename="../sources/windows/CombatDialog.cpp" line="103"/>
+        <location filename="../sources/windows/CombatDialog.cpp" line="135"/>
         <source>Confirmation</source>
         <translation>Confirmation</translation>
     </message>
     <message>
-        <location filename="../sources/windows/CombatDialog.cpp" line="107"/>
+        <location filename="../sources/windows/CombatDialog.cpp" line="103"/>
         <source>You are about to remove %1 from the combat manager. Are you sure you want to do it?</source>
         <translation>Vous êtes sur le point de retirer %1 du gestionnaire de combat. Êtes-vous sûr de vouloir le faire ?</translation>
     </message>
     <message>
-        <location filename="../sources/windows/CombatDialog.cpp" line="139"/>
+        <location filename="../sources/windows/CombatDialog.cpp" line="135"/>
         <source>You are about to close the combat manager. You will lose all information about the ongoing combat. Are you sure you want to do it?</source>
         <translation>Vous êtes sur le point de fermer le gestionnaire de combat. Vous perdrez toutes les informations sur le combat en cours. Êtes-vous sûr de vouloir le faire ?</translation>
     </message>
 </context>
+<context>
+    <name>customTab</name>
+    <message>
+        <location filename="../sources/widgets/QCustomTabWidget.cpp" line="157"/>
+        <source>&amp;Rename</source>
+        <translation>&amp;Renommer</translation>
+    </message>
+    <message>
+        <location filename="../sources/widgets/QCustomTabWidget.cpp" line="158"/>
+        <source>Rename the note</source>
+        <translation>Renomme la note</translation>
+    </message>
+    <message>
+        <location filename="../sources/widgets/QCustomTabWidget.cpp" line="160"/>
+        <source>&amp;Close</source>
+        <translation>&amp;Fermer</translation>
+    </message>
+    <message>
+        <location filename="../sources/widgets/QCustomTabWidget.cpp" line="161"/>
+        <source>Close the note</source>
+        <translation>Ferme la note</translation>
+    </message>
+</context>
 <context>
     <name>customTable</name>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="773"/>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="783"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="787"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="797"/>
         <source>&amp;Add</source>
         <translation>&amp;Ajouter</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="772"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="786"/>
         <source>&amp;Property</source>
         <translation>&amp;Propriété</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="774"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="788"/>
         <source>Add a new property</source>
         <translation>Ajoute une nouvelle propriété</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="776"/>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="786"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="790"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="800"/>
         <source>&amp;Remove</source>
         <translation>&amp;Supprimer</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="779"/>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="789"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="793"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="803"/>
         <source>&amp;Edit</source>
         <translation>&amp;Éditer</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="777"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="791"/>
         <source>Remove the property</source>
         <translation>Supprime la propriété</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="780"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="794"/>
         <source>Edit the property</source>
         <translation>Édite la propriété</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="782"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="796"/>
         <source>&amp;Character</source>
         <translation>P&amp;ersonnage</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="784"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="798"/>
         <source>Add a new character</source>
         <translation>Ajoute un nouveau personnage</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="787"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="801"/>
         <source>Remove the character</source>
         <translation>Supprime le personnage</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="790"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="804"/>
         <source>Edit the character</source>
         <translation>Édite le personnage</translation>
     </message>
+    <message>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="806"/>
+        <source>Double click to display the note associated with a character</source>
+        <translation>Double-cliquez pour afficher la note associée à un personnage</translation>
+    </message>
 </context>
 <context>
     <name>customTree</name>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="746"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="163"/>
+        <source>Display the note</source>
+        <translation>Affiche la note</translation>
+    </message>
+    <message>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="806"/>
         <source>&amp;None</source>
         <translation>&amp;Aucun</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="747"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="807"/>
         <source>Untag the item</source>
         <translation>Retire toute étiquette de l&apos;item</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="749"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="809"/>
         <source>In &amp;progress</source>
         <translation>En &amp;cours</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="750"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="810"/>
         <source>Tag the item as being in progress</source>
         <translation>Marque l&apos;item comme étant en cours</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="752"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="812"/>
         <source>&amp;Failed</source>
         <translation>&amp;Échoué</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="753"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="813"/>
         <source>Tag the item as failed</source>
         <translation>Marque l&apos;item comme échoué</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="755"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="815"/>
         <source>&amp;Succeeded</source>
         <translation>&amp;Réussi</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="756"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="816"/>
         <source>Tag the item as succeeded</source>
         <translation>Marque l&apos;item comme réussi</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="758"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="818"/>
         <source>&amp;Add</source>
         <translation>A&amp;jouter</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="759"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="819"/>
         <source>Add a new item</source>
         <translation>Ajoute un nouvel item</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="761"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="821"/>
         <source>&amp;Remove</source>
         <translation>&amp;Supprimer</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="762"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="822"/>
         <source>Remove the item</source>
         <translation>Supprime l&apos;item</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="764"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="824"/>
         <source>&amp;Edit</source>
         <translation>É&amp;diter</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="765"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="825"/>
         <source>Edit the item</source>
         <translation>Édite l&apos;item</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="768"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="828"/>
         <source>E&amp;xport</source>
         <translation>E&amp;xporter</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="769"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="829"/>
         <source>Export the file associated to the item</source>
         <translation>Exporte le fichier associé à l&apos;item</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="804"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="864"/>
         <source>Select where to export the file</source>
         <translation>Sélectionnez où exporter le fichier</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="809"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="869"/>
         <source>Error</source>
         <translation>Erreur</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="809"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="869"/>
         <source>Unable to export the file</source>
         <translation>Impossible d&apos;exporter le fichier</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="96"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="97"/>
         <source>Audio files can be played only in the Music and Sound effects modules.</source>
         <translation>Les fichiers audios ne peuvent être joués que dans les modules Musique et Bruitages.</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="147"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="152"/>
         <source>Play the audio file</source>
         <translation>Joue le fichier audio</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="110"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="111"/>
         <source>Unable to display the file</source>
         <translation>Impossible d&apos;afficher le fichier</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="148"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="153"/>
         <source>P&amp;lay</source>
         <translation>J&amp;ouer</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="153"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="158"/>
         <source>Display the image</source>
         <translation>Affiche l&apos;image</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="154"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="159"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="164"/>
         <source>Disp&amp;lay</source>
         <translation>A&amp;fficher</translation>
     </message>
@@ -365,9 +399,14 @@
     </message>
     <message>
         <location filename="../sources/widgets/QCustomTreeWidgetItem.cpp" line="75"/>
-        <source>Double click to show the file</source>
+        <source>Double click to display the image</source>
         <translation>Double-cliquez pour afficher l&apos;image</translation>
     </message>
+    <message>
+        <location filename="../sources/widgets/QCustomTreeWidgetItem.cpp" line="83"/>
+        <source>Double click to display the note</source>
+        <translation>Double-cliquez pour afficher la note</translation>
+    </message>
 </context>
 <context>
     <name>diceDialog</name>
@@ -387,17 +426,47 @@
         <translation>Nombre de dés :</translation>
     </message>
     <message>
-        <location filename="../sources/windows/DiceDialog.ui" line="118"/>
+        <location filename="../sources/windows/DiceDialog.ui" line="125"/>
+        <source>Sum:</source>
+        <translation>Somme :</translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/DiceDialog.ui" line="167"/>
+        <source>Equal to</source>
+        <translation>Égal à</translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/DiceDialog.ui" line="174"/>
+        <source>Minimum:</source>
+        <translation>Minimum :</translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/DiceDialog.ui" line="181"/>
+        <source>Maximum:</source>
+        <translation>Maximum :</translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/DiceDialog.ui" line="195"/>
+        <source>At least</source>
+        <translation>Au moins</translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/DiceDialog.ui" line="202"/>
+        <source>At most</source>
+        <translation>Au plus</translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/DiceDialog.ui" line="227"/>
         <source>&amp;Throw</source>
         <translation>&amp;Lancer</translation>
     </message>
     <message>
-        <location filename="../sources/windows/DiceDialog.ui" line="128"/>
+        <location filename="../sources/windows/DiceDialog.ui" line="237"/>
         <source>&amp;Reset</source>
         <translation>&amp;Mettre à zéro</translation>
     </message>
     <message>
-        <location filename="../sources/windows/DiceDialog.ui" line="135"/>
+        <location filename="../sources/windows/DiceDialog.ui" line="244"/>
         <source>&amp;Close</source>
         <translation>&amp;Fermer</translation>
     </message>
@@ -406,7 +475,7 @@
     <name>itemDialog</name>
     <message>
         <location filename="../sources/windows/ItemDialog.ui" line="17"/>
-        <location filename="../sources/windows/ItemDialog.cpp" line="176"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="173"/>
         <source>Create a new item</source>
         <translation>Créer un nouvel item</translation>
     </message>
@@ -452,54 +521,59 @@
     </message>
     <message>
         <location filename="../sources/windows/ItemDialog.ui" line="117"/>
+        <source>N&amp;ote</source>
+        <translation>N&amp;ote</translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/ItemDialog.ui" line="128"/>
         <source>A&amp;udio</source>
         <translation>A&amp;udio</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.ui" line="128"/>
+        <location filename="../sources/windows/ItemDialog.ui" line="139"/>
         <source>I&amp;mage</source>
         <translation>&amp;Image</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.ui" line="141"/>
+        <location filename="../sources/windows/ItemDialog.ui" line="152"/>
         <source>File:</source>
         <translation>Fichier :</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.ui" line="172"/>
+        <location filename="../sources/windows/ItemDialog.ui" line="183"/>
         <source>&amp;Add</source>
         <translation>A&amp;jouter</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.ui" line="183"/>
-        <location filename="../sources/windows/ItemDialog.cpp" line="179"/>
+        <location filename="../sources/windows/ItemDialog.ui" line="194"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="176"/>
         <source>C&amp;hild</source>
         <translation>En&amp;fant</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.ui" line="194"/>
+        <location filename="../sources/windows/ItemDialog.ui" line="205"/>
         <source>&amp;Cancel</source>
         <translation>A&amp;nnuler</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.cpp" line="209"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="207"/>
         <source>Audio files (*)</source>
         <translation>Fichiers audio (*)</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.cpp" line="82"/>
-        <location filename="../sources/windows/ItemDialog.cpp" line="102"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="79"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="99"/>
         <source>You must select a file before validating.</source>
         <translation>Vous devez sélectionner un fichier avant de valider.</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.cpp" line="87"/>
-        <location filename="../sources/windows/ItemDialog.cpp" line="107"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="84"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="104"/>
         <source>You must fill the content before validating.</source>
         <translation>Vous devez remplir le contenu avant de valider.</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.cpp" line="145"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="142"/>
         <source>Select the image file to associate to the item</source>
         <translation>Sélectionnez le fichier image à associer à l&apos;item</translation>
     </message>
@@ -509,25 +583,25 @@
         <translation>Sélectionnez le fichier audio à associer à l&apos;item</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.cpp" line="82"/>
-        <location filename="../sources/windows/ItemDialog.cpp" line="87"/>
-        <location filename="../sources/windows/ItemDialog.cpp" line="102"/>
-        <location filename="../sources/windows/ItemDialog.cpp" line="107"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="79"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="84"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="99"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="104"/>
         <source>Incomplete data</source>
         <translation>Données incomplètes</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.cpp" line="145"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="142"/>
         <source>Image files (*.jpg *.jpeg *.png *.bmp *.svg)</source>
         <translation>Fichiers image (*.jpg *.jpeg *.png *.bmp *.svg)</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.cpp" line="160"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="157"/>
         <source>Edit the item</source>
         <translation>Éditer l&apos;item</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.cpp" line="163"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="160"/>
         <source>&amp;Validate</source>
         <translation>&amp;Valider</translation>
     </message>
@@ -540,12 +614,12 @@
         <translation>Historique</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="158"/>
+        <location filename="../sources/windows/MainWindow.ui" line="171"/>
         <source>Sound effects</source>
         <translation>Bruitages</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="200"/>
+        <location filename="../sources/windows/MainWindow.ui" line="213"/>
         <source>Music</source>
         <translation>Musique</translation>
     </message>
@@ -560,370 +634,380 @@
         <translation>Notes</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="133"/>
+        <location filename="../sources/windows/MainWindow.ui" line="146"/>
         <source>Characters</source>
         <translation>Personnages</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="242"/>
+        <location filename="../sources/windows/MainWindow.ui" line="255"/>
         <source>Browse the music file</source>
         <translation>Navigue dans le fichier musical</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="262"/>
+        <location filename="../sources/windows/MainWindow.ui" line="275"/>
         <source>Play/Pause/Resume the music</source>
         <translation>Joue/pause/reprend la musique</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="265"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="490"/>
+        <location filename="../sources/windows/MainWindow.ui" line="278"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="501"/>
         <source>&amp;Play</source>
         <translation>&amp;Lecture</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="282"/>
+        <location filename="../sources/windows/MainWindow.ui" line="295"/>
         <source>Enable/Disable loop playing</source>
         <translation>Active/désactive le jeu en boucle</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="285"/>
+        <location filename="../sources/windows/MainWindow.ui" line="298"/>
         <source>&amp;Loop</source>
         <translation>&amp;Boucle</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="311"/>
+        <location filename="../sources/windows/MainWindow.ui" line="324"/>
         <source>&amp;Game</source>
         <translation>&amp;Jeu</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="335"/>
+        <location filename="../sources/windows/MainWindow.ui" line="350"/>
         <source>&amp;View</source>
         <translation>&amp;Affichage</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="342"/>
+        <location filename="../sources/windows/MainWindow.ui" line="357"/>
         <source>&amp;Language</source>
         <translation>&amp;Langue</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="347"/>
+        <location filename="../sources/windows/MainWindow.ui" line="362"/>
         <source>&amp;Interface</source>
         <translation>&amp;Interface</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="360"/>
+        <location filename="../sources/windows/MainWindow.ui" line="375"/>
         <source>&amp;Edit</source>
         <translation>&amp;Édition</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="367"/>
+        <location filename="../sources/windows/MainWindow.ui" line="382"/>
         <source>&amp;Tools</source>
         <translation>&amp;Outils</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="381"/>
+        <location filename="../sources/windows/MainWindow.ui" line="396"/>
         <source>&amp;New</source>
         <translation>&amp;Nouveau</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="384"/>
+        <location filename="../sources/windows/MainWindow.ui" line="399"/>
         <source>Create a new game</source>
         <translation>Crée un nouveau jeu</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="392"/>
+        <location filename="../sources/windows/MainWindow.ui" line="407"/>
         <source>&amp;Load</source>
         <translation>&amp;Charger</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="395"/>
+        <location filename="../sources/windows/MainWindow.ui" line="410"/>
         <source>Load a game</source>
         <translation>Charge un jeu</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="403"/>
+        <location filename="../sources/windows/MainWindow.ui" line="418"/>
         <source>&amp;Save</source>
         <translation>&amp;Enregistrer</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="406"/>
+        <location filename="../sources/windows/MainWindow.ui" line="421"/>
         <source>Save the current game</source>
         <translation>Sauvegarde le jeu en cours</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="414"/>
+        <location filename="../sources/windows/MainWindow.ui" line="429"/>
         <source>S&amp;ave as</source>
         <translation>Enregistrer &amp;sous</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="417"/>
+        <location filename="../sources/windows/MainWindow.ui" line="432"/>
         <source>Save the current game in a new file</source>
         <translation>Sauvegarde le jeu en cours dans un nouveau fichier</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="425"/>
+        <location filename="../sources/windows/MainWindow.ui" line="440"/>
         <source>&amp;Quit</source>
         <translation>&amp;Quitter</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="428"/>
+        <location filename="../sources/windows/MainWindow.ui" line="443"/>
         <source>Exit the application</source>
         <translation>Sort de l&apos;application</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="602"/>
+        <location filename="../sources/windows/MainWindow.ui" line="617"/>
         <source>About &amp;Qt</source>
         <translation>À propos de &amp;Qt</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="605"/>
+        <location filename="../sources/windows/MainWindow.ui" line="620"/>
         <source>Display information about Qt</source>
         <translation>Informations à propos de Qt</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="439"/>
+        <location filename="../sources/windows/MainWindow.ui" line="625"/>
+        <source>&amp;Release notes</source>
+        <translation>&amp;Notes de version</translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/MainWindow.ui" line="628"/>
+        <source>Display the release notes</source>
+        <translation>Affiche les notes de version</translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/MainWindow.ui" line="454"/>
         <source>Display information about GM-Assistant</source>
         <translation>Informations à propos de GM-Assistant</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="447"/>
+        <location filename="../sources/windows/MainWindow.ui" line="462"/>
         <source>&amp;Reload</source>
         <translation>&amp;Recharger</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="450"/>
+        <location filename="../sources/windows/MainWindow.ui" line="465"/>
         <source>Reload the current game</source>
         <translation>Recharge le jeu en cours</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="458"/>
+        <location filename="../sources/windows/MainWindow.ui" line="473"/>
         <source>R&amp;ecent</source>
         <translation>R&amp;écents</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="461"/>
+        <location filename="../sources/windows/MainWindow.ui" line="476"/>
         <source>Load a recently opened game</source>
         <translation>Charge un jeu ouvert récemment</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="472"/>
+        <location filename="../sources/windows/MainWindow.ui" line="487"/>
         <source>&amp;Full</source>
         <translation>&amp;Complète</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="489"/>
+        <location filename="../sources/windows/MainWindow.ui" line="504"/>
         <source>Tools shown: Music and Sound effects</source>
         <translation>Outils affichés : Musique et Bruitages</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="564"/>
+        <location filename="../sources/windows/MainWindow.ui" line="579"/>
         <source>Throw virtual dices</source>
         <translation>Jette des dés virtuels</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="572"/>
+        <location filename="../sources/windows/MainWindow.ui" line="587"/>
         <source>&amp;Combat manager</source>
         <translation>&amp;Gestionnaire de combat</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="575"/>
+        <location filename="../sources/windows/MainWindow.ui" line="590"/>
         <source>Manage round per round combats</source>
         <translation>Gère les combats au tour par tour</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="586"/>
+        <location filename="../sources/windows/MainWindow.ui" line="601"/>
         <source>&amp;English</source>
         <translation></translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="591"/>
+        <location filename="../sources/windows/MainWindow.ui" line="606"/>
         <source>&amp;Metadata</source>
         <translation>&amp;Métadonnées</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="594"/>
+        <location filename="../sources/windows/MainWindow.ui" line="609"/>
         <source>Edit the game metadata</source>
         <translation>Édite les métadonnées du jeu</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="328"/>
+        <location filename="../sources/windows/MainWindow.ui" line="341"/>
         <source>&amp;Help</source>
         <translation>A&amp;ide</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="436"/>
+        <location filename="../sources/windows/MainWindow.ui" line="451"/>
         <source>About &amp;GM-Assistant</source>
         <translation>À propos de &amp;GM-Assistant</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="475"/>
+        <location filename="../sources/windows/MainWindow.ui" line="490"/>
         <source>Tools shown: Plot, Notes, Characters, History, Music and Sound effects</source>
         <translation>Outils affichés : Intrigue, Notes, Personnages, Historique, Musique et Bruitages</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="486"/>
+        <location filename="../sources/windows/MainWindow.ui" line="501"/>
         <source>&amp;Music</source>
         <translation>&amp;Musique</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="500"/>
+        <location filename="../sources/windows/MainWindow.ui" line="515"/>
         <source>&amp;Simple</source>
         <translation>&amp;Simple</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="503"/>
+        <location filename="../sources/windows/MainWindow.ui" line="518"/>
         <source>Tools shown: Plot, Music and Sound effects</source>
         <translation>Outils affichés : Intrigue, Musique et Bruitages</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="514"/>
+        <location filename="../sources/windows/MainWindow.ui" line="529"/>
         <source>&amp;Design</source>
         <translation>C&amp;onception</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="539"/>
+        <location filename="../sources/windows/MainWindow.ui" line="554"/>
         <source>&amp;Undo</source>
         <translation>&amp;Annuler</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="542"/>
+        <location filename="../sources/windows/MainWindow.ui" line="557"/>
         <source>Undo the last modification</source>
         <translation>Annule la dernière modification</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="550"/>
+        <location filename="../sources/windows/MainWindow.ui" line="565"/>
         <source>&amp;Redo</source>
         <translation>&amp;Refaire</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="553"/>
+        <location filename="../sources/windows/MainWindow.ui" line="568"/>
         <source>Redo the last undone modification</source>
         <translation>Refait la dernière modification annulée</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="561"/>
+        <location filename="../sources/windows/MainWindow.ui" line="576"/>
         <source>&amp;Dice simulator</source>
         <translation>&amp;Simulateur de dés</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="517"/>
+        <location filename="../sources/windows/MainWindow.ui" line="532"/>
         <source>Tools shown: Plot, Characters and Notes</source>
         <translation>Outils affichés : Intrigue, Personnages et Notes</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="528"/>
+        <location filename="../sources/windows/MainWindow.ui" line="543"/>
         <source>&amp;No Music</source>
         <translation>S&amp;ans son</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="531"/>
+        <location filename="../sources/windows/MainWindow.ui" line="546"/>
         <source>Tools shown: Plot, Characters, History and Notes</source>
         <translation>Outils affichés : Intrigue, Personnages, Historique et Notes</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="464"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="940"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="475"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="956"/>
         <source>&amp;Pause</source>
         <translation>&amp;Pause</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="458"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="469"/>
         <source>&amp;Resume</source>
         <translation>&amp;Reprise</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="96"/>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="110"/>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="495"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="306"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="312"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="353"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="398"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="512"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="551"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="564"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="570"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="880"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="97"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="111"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="537"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="316"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="322"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="363"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="408"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="523"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="562"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="575"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="581"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="896"/>
         <source>Error</source>
         <translation>Erreur</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="295"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="305"/>
         <source>Select the file to open</source>
         <translation>Sélectionnez le fichier à ouvrir</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="295"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="305"/>
         <source>GM-Assistant files (*.gms *.gma);;XML files (*.xml)</source>
         <translation>Fichiers GM-Assistant (*.gms *.gma);;Fichiers XML (*.xml)</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="312"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="570"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="322"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="581"/>
         <source>The game will be loaded anyway, but some features might not work properly.</source>
         <translation>Le jeu va tout de même être chargé, mais certaines fonctionnalités peuvent ne pas fonctionner normalement.</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="312"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="570"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="322"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="581"/>
         <source>The game cannot be loaded correctly for the following reason:</source>
         <translation>Le jeu n&apos;a pas pu être chargé pour la raison suivante :</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="322"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="341"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="578"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="332"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="351"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="589"/>
         <source>Warning</source>
         <translation>Attention</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="322"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="578"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="332"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="589"/>
         <source>The syntax of the game you have just loaded is not rigourously correct. Would you like to fix it now?</source>
         <translation>La syntaxe du jeu que vous venez de charger n&apos;est pas rigoureusement correcte. Voulez-vous la corriger maintenant ?</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="341"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="351"/>
         <source>The game you want to save does not use the latest version of GM-Assistant files. Do you want to update it? If no, some features may not be saved properly.</source>
         <translation>Le jeu que vous voulez sauvegarder n&apos;utilise pas la dernière version de fichiers GM-Assistant. Voulez-vous le mettre à jour ? Si non, certaines fonctionnalités peuvent ne pas être sauvegardées correctement.</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="365"/>
-        <source>GM-Assistant files (1.2) (*.gms)</source>
-        <translation>Fichiers GM-Assistant (1.2) (*.gms)</translation>
+        <location filename="../sources/windows/MainWindow.cpp" line="375"/>
+        <source>GM-Assistant files (*.gms)</source>
+        <translation>Fichiers GM-Assistant (*.gms)</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="368"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="378"/>
         <source>;;GM-Assistant files (1.1) (*.gma);;GM-Assistant files (1.0) (*.xml)</source>
         <translation>;;Fichiers GM-Assistant (1.1) (*.gma);;Fichiers GM-Assistant (1.0) (*.xml)</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="370"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="380"/>
         <source>Select the file to save</source>
         <translation>Sélectionnez le fichier à sauvegarder</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="512"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="523"/>
         <source>Unable to play the file</source>
         <translation>Impossible de jouer le fichier</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="551"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="562"/>
         <source>The file &quot;%1&quot; does not exist.</source>
         <translation>Le fichier &quot;%1&quot; n&apos;existe pas.</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="827"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="843"/>
         <source>Confirmation</source>
         <translation>Confirmation</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="827"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="843"/>
         <source>The current game has been modified since the last save. If you continue, unsaved changes will be discarded.</source>
         <translation>Le jeu en cours a été modifié depuis la dernière sauvegarde. Si vous continuez, les changements non sauvegardés seront perdus.</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="735"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="746"/>
         <source>New game</source>
         <translation>Nouveau jeu</translation>
     </message>
@@ -976,6 +1060,47 @@
         <translation>Jeu de rôle</translation>
     </message>
 </context>
+<context>
+    <name>releaseNotesDialog</name>
+    <message>
+        <location filename="../sources/windows/ReleaseNotesDialog.ui" line="14"/>
+        <source>Release notes</source>
+        <translation>Notes de version</translation>
+    </message>
+</context>
+<context>
+    <name>renameNoteDialog</name>
+    <message>
+        <location filename="../sources/windows/RenameNoteDialog.ui" line="17"/>
+        <source>New title</source>
+        <translation>Nouveau titre</translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/RenameNoteDialog.ui" line="29"/>
+        <source>Title of the note:</source>
+        <translation>Titre de la note :</translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/RenameNoteDialog.ui" line="41"/>
+        <source>&amp;Validate</source>
+        <translation>&amp;Valider</translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/RenameNoteDialog.ui" line="52"/>
+        <source>&amp;Cancel</source>
+        <translation>A&amp;nnuler</translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/RenameNoteDialog.cpp" line="41"/>
+        <source>Incomplete data</source>
+        <translation>Données incomplètes</translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/RenameNoteDialog.cpp" line="41"/>
+        <source>You must fill the title before validating.</source>
+        <translation>Vous devez remplir le titre avant de valider.</translation>
+    </message>
+</context>
 <context>
     <name>selectCharacterDialog</name>
     <message>
@@ -1004,12 +1129,12 @@
         <translation>Personnages impliqués</translation>
     </message>
     <message>
-        <location filename="../sources/windows/SelectCharacterDialog.ui" line="81"/>
+        <location filename="../sources/windows/SelectCharacterDialog.ui" line="74"/>
         <source>&amp;Up</source>
         <translation>&amp;Haut</translation>
     </message>
     <message>
-        <location filename="../sources/windows/SelectCharacterDialog.ui" line="92"/>
+        <location filename="../sources/windows/SelectCharacterDialog.ui" line="85"/>
         <source>&amp;Down</source>
         <translation>&amp;Bas</translation>
     </message>
diff --git a/translations/gmassistant_it.ts b/translations/gmassistant_it.ts
index 0abf4d1..63073b3 100644
--- a/translations/gmassistant_it.ts
+++ b/translations/gmassistant_it.ts
@@ -126,7 +126,7 @@
     </message>
     <message>
         <location filename="../sources/windows/CombatDialog.ui" line="20"/>
-        <location filename="../sources/windows/CombatDialog.cpp" line="75"/>
+        <location filename="../sources/windows/CombatDialog.cpp" line="71"/>
         <source>Current character:</source>
         <translation>Personaggio corrente:</translation>
     </message>
@@ -151,210 +151,244 @@
         <translation>&amp;Chiudi</translation>
     </message>
     <message>
-        <location filename="../sources/windows/CombatDialog.cpp" line="107"/>
-        <location filename="../sources/windows/CombatDialog.cpp" line="139"/>
+        <location filename="../sources/windows/CombatDialog.cpp" line="103"/>
+        <location filename="../sources/windows/CombatDialog.cpp" line="135"/>
         <source>Confirmation</source>
         <translation>Conferma</translation>
     </message>
     <message>
-        <location filename="../sources/windows/CombatDialog.cpp" line="107"/>
+        <location filename="../sources/windows/CombatDialog.cpp" line="103"/>
         <source>You are about to remove %1 from the combat manager. Are you sure you want to do it?</source>
         <translatorcomment>Same combat manager doubt.</translatorcomment>
         <translation>Stai per rimuovere %1 dal gestore di combattimento. Sei sicuro di volerlo fare?</translation>
     </message>
     <message>
-        <location filename="../sources/windows/CombatDialog.cpp" line="139"/>
+        <location filename="../sources/windows/CombatDialog.cpp" line="135"/>
         <source>You are about to close the combat manager. You will lose all information about the ongoing combat. Are you sure you want to do it?</source>
         <translation>Stai per chiudere il gestore di combattimento. Perderai tutte le informazioni sul combattimento. Sei sicuro di volerlo fare?</translation>
     </message>
 </context>
+<context>
+    <name>customTab</name>
+    <message>
+        <location filename="../sources/widgets/QCustomTabWidget.cpp" line="172"/>
+        <source>&amp;Rename</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sources/widgets/QCustomTabWidget.cpp" line="173"/>
+        <source>Rename the note</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sources/widgets/QCustomTabWidget.cpp" line="175"/>
+        <source>&amp;Close</source>
+        <translation type="unfinished">&amp;Chiudi</translation>
+    </message>
+    <message>
+        <location filename="../sources/widgets/QCustomTabWidget.cpp" line="176"/>
+        <source>Close the note</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>customTable</name>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="772"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="783"/>
         <source>&amp;Property</source>
         <translation>&amp;Proprietà</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="773"/>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="783"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="784"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="794"/>
         <source>&amp;Add</source>
         <translation>&amp;Aggiungi</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="774"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="785"/>
         <source>Add a new property</source>
         <translation>Aggiungi una nuova proprietà</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="776"/>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="786"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="787"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="797"/>
         <source>&amp;Remove</source>
         <translation>&amp;Rimuovi</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="777"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="788"/>
         <source>Remove the property</source>
         <translation>Rimuovi la proprietà</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="779"/>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="789"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="790"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="800"/>
         <source>&amp;Edit</source>
         <translation>&amp;Modifica</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="780"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="791"/>
         <source>Edit the property</source>
         <translation>Modifica la proprietà</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="782"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="793"/>
         <source>&amp;Character</source>
         <translation>P&amp;ersonaggio</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="784"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="795"/>
         <source>Add a new character</source>
         <translation>Aggiungi un nuovo personaggio</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="787"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="798"/>
         <source>Remove the character</source>
         <translation>Rimuovi il personaggio</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="790"/>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="801"/>
         <source>Edit the character</source>
         <translation>Modifica il personaggio</translation>
     </message>
+    <message>
+        <location filename="../sources/widgets/QCustomTableWidget.cpp" line="803"/>
+        <source>Double click to display the note associated with a character</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>customTree</name>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="96"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="97"/>
         <source>Audio files can be played only in the Music and Sound effects modules.</source>
         <translation>I file audio possono essere riprodotti solo nei moduli Musica e Effetti sonori.</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="110"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="111"/>
         <source>Unable to display the file</source>
         <translation>Impossibile visualizzare il file</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="147"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="152"/>
         <source>Play the audio file</source>
         <translation>Riproduci il file audio</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="148"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="153"/>
         <source>P&amp;lay</source>
         <translation>R&amp;iproduci</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="153"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="158"/>
         <source>Display the image</source>
         <translation>Visualizza l&apos;immagine</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="154"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="159"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="164"/>
         <source>Disp&amp;lay</source>
         <translation>&amp;Visualizza</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="746"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="163"/>
+        <source>Display the note</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="806"/>
         <source>&amp;None</source>
         <translation>&amp;Nessuno</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="747"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="807"/>
         <source>Untag the item</source>
         <translatorcomment>What do you mean by tag?</translatorcomment>
         <translation>Rimuovi il segnalino dall&apos;oggetto</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="749"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="809"/>
         <source>In &amp;progress</source>
         <translation>In &amp;corso</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="750"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="810"/>
         <source>Tag the item as being in progress</source>
         <translatorcomment>I assumed &apos;in progress&apos; meant &apos;not ready yet, still working on it&apos;.</translatorcomment>
         <translation>Segna l&apos;oggetto come in corso</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="752"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="812"/>
         <source>&amp;Failed</source>
         <translation>&amp;Fallito</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="753"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="813"/>
         <source>Tag the item as failed</source>
         <translation>Segna l&apos;oggetto come fallito</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="755"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="815"/>
         <source>&amp;Succeeded</source>
         <translation>&amp;Riuscito</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="756"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="816"/>
         <source>Tag the item as succeeded</source>
         <translation>Segna l&apos;oggetto come riuscito</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="758"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="818"/>
         <source>&amp;Add</source>
         <translation>&amp;Aggiungi</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="759"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="819"/>
         <source>Add a new item</source>
         <translation>Aggiungi un nuovo oggetto</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="761"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="821"/>
         <source>&amp;Remove</source>
         <translation>R&amp;imuovi</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="762"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="822"/>
         <source>Remove the item</source>
         <translation>Rimuovi l&apos;oggetto</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="764"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="824"/>
         <source>&amp;Edit</source>
         <translation>&amp;Modifica</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="765"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="825"/>
         <source>Edit the item</source>
         <translation>Modifica l&apos;oggetto</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="768"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="828"/>
         <source>E&amp;xport</source>
         <translation>&amp;Esporta</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="769"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="829"/>
         <source>Export the file associated to the item</source>
         <translation>Esporta il file associato all&apos;oggetto</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="804"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="864"/>
         <source>Select where to export the file</source>
         <translation>Seleziona dove esportare il file</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="809"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="869"/>
         <source>Error</source>
         <translation>Errore</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="809"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="869"/>
         <source>Unable to export the file</source>
         <translation>Impossibile esportare il file</translation>
     </message>
@@ -370,8 +404,13 @@
     </message>
     <message>
         <location filename="../sources/widgets/QCustomTreeWidgetItem.cpp" line="75"/>
-        <source>Double click to show the file</source>
-        <translation>Doppio click per visualizzare il file</translation>
+        <source>Double click to display the image</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sources/widgets/QCustomTreeWidgetItem.cpp" line="83"/>
+        <source>Double click to display the note</source>
+        <translation type="unfinished"></translation>
     </message>
 </context>
 <context>
@@ -411,7 +450,7 @@
     <name>itemDialog</name>
     <message>
         <location filename="../sources/windows/ItemDialog.ui" line="17"/>
-        <location filename="../sources/windows/ItemDialog.cpp" line="176"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="173"/>
         <source>Create a new item</source>
         <translation>Crea un nuovo oggetto</translation>
     </message>
@@ -458,32 +497,37 @@
     </message>
     <message>
         <location filename="../sources/windows/ItemDialog.ui" line="117"/>
+        <source>N&amp;ote</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/ItemDialog.ui" line="128"/>
         <source>A&amp;udio</source>
         <translation>A&amp;udio</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.ui" line="128"/>
+        <location filename="../sources/windows/ItemDialog.ui" line="139"/>
         <source>I&amp;mage</source>
         <translation>&amp;Immagine</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.ui" line="141"/>
+        <location filename="../sources/windows/ItemDialog.ui" line="152"/>
         <source>File:</source>
         <translation>File:</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.ui" line="172"/>
+        <location filename="../sources/windows/ItemDialog.ui" line="183"/>
         <source>&amp;Add</source>
         <translation>&amp;Aggiungi</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.ui" line="183"/>
-        <location filename="../sources/windows/ItemDialog.cpp" line="179"/>
+        <location filename="../sources/windows/ItemDialog.ui" line="194"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="176"/>
         <source>C&amp;hild</source>
         <translation>Ba&amp;mbino</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.ui" line="194"/>
+        <location filename="../sources/windows/ItemDialog.ui" line="205"/>
         <source>&amp;Cancel</source>
         <translation>Annu&amp;lla</translation>
     </message>
@@ -493,47 +537,47 @@
         <translation>Seleziona il file audio da associare all&apos;oggetto</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.cpp" line="82"/>
-        <location filename="../sources/windows/ItemDialog.cpp" line="102"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="79"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="99"/>
         <source>You must select a file before validating.</source>
         <translation>Devi selezionare un file prima di confermare.</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.cpp" line="82"/>
-        <location filename="../sources/windows/ItemDialog.cpp" line="87"/>
-        <location filename="../sources/windows/ItemDialog.cpp" line="102"/>
-        <location filename="../sources/windows/ItemDialog.cpp" line="107"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="79"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="84"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="99"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="104"/>
         <source>Incomplete data</source>
         <translation>Dati incompleti</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.cpp" line="87"/>
-        <location filename="../sources/windows/ItemDialog.cpp" line="107"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="84"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="104"/>
         <source>You must fill the content before validating.</source>
         <translation>Devi inserire il contenuto prima di confermare.</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.cpp" line="145"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="142"/>
         <source>Select the image file to associate to the item</source>
         <translation>Seleziona il file immagine da associare all&apos;oggetto</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.cpp" line="145"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="142"/>
         <source>Image files (*.jpg *.jpeg *.png *.bmp *.svg)</source>
         <translation>File immagine (*.jpg *.jpeg *.png *.bmp *.svg)</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.cpp" line="160"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="157"/>
         <source>Edit the item</source>
         <translation>Modifica l&apos;oggetto</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.cpp" line="163"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="160"/>
         <source>&amp;Validate</source>
         <translation>C&amp;onferma</translation>
     </message>
     <message>
-        <location filename="../sources/windows/ItemDialog.cpp" line="209"/>
+        <location filename="../sources/windows/ItemDialog.cpp" line="207"/>
         <source>Audio files (*)</source>
         <translation>File audio (*)</translation>
     </message>
@@ -557,384 +601,384 @@
         <translation>Appunti</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="133"/>
+        <location filename="../sources/windows/MainWindow.ui" line="146"/>
         <source>Characters</source>
         <translation>Personaggi</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="158"/>
+        <location filename="../sources/windows/MainWindow.ui" line="171"/>
         <source>Sound effects</source>
         <translation>Effetti sonori</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="200"/>
+        <location filename="../sources/windows/MainWindow.ui" line="213"/>
         <source>Music</source>
         <translation>Musica</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="242"/>
+        <location filename="../sources/windows/MainWindow.ui" line="255"/>
         <source>Browse the music file</source>
         <translation>Scorri il file musicale</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="262"/>
+        <location filename="../sources/windows/MainWindow.ui" line="275"/>
         <source>Play/Pause/Resume the music</source>
         <translation>Riproduci/interrompi/riprendi la musica</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="265"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="490"/>
+        <location filename="../sources/windows/MainWindow.ui" line="278"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="501"/>
         <source>&amp;Play</source>
         <translation>&amp;Riproduci</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="282"/>
+        <location filename="../sources/windows/MainWindow.ui" line="295"/>
         <source>Enable/Disable loop playing</source>
         <translation>Attiva/Disattiva riproduzione continua</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="285"/>
+        <location filename="../sources/windows/MainWindow.ui" line="298"/>
         <source>&amp;Loop</source>
         <translatorcomment>The adjective &quot;continua&quot; used to render &quot;loop playing&quot; would be ambiguous here.</translatorcomment>
         <translation>&amp;Loop</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="311"/>
+        <location filename="../sources/windows/MainWindow.ui" line="324"/>
         <source>&amp;Game</source>
         <translation>&amp;Gioco</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="328"/>
+        <location filename="../sources/windows/MainWindow.ui" line="341"/>
         <source>&amp;Help</source>
         <translation>&amp;Aiuto</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="335"/>
+        <location filename="../sources/windows/MainWindow.ui" line="348"/>
         <source>&amp;View</source>
         <translatorcomment>Is it intended as a verb?</translatorcomment>
         <translation>&amp;Visualizza</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="342"/>
+        <location filename="../sources/windows/MainWindow.ui" line="355"/>
         <source>&amp;Language</source>
         <translation>&amp;Lingua</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="347"/>
+        <location filename="../sources/windows/MainWindow.ui" line="360"/>
         <source>&amp;Interface</source>
         <translation>&amp;Interfaccia</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="360"/>
+        <location filename="../sources/windows/MainWindow.ui" line="373"/>
         <source>&amp;Edit</source>
         <translation>&amp;Modifica</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="367"/>
+        <location filename="../sources/windows/MainWindow.ui" line="380"/>
         <source>&amp;Tools</source>
         <translation>&amp;Strumenti</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="381"/>
+        <location filename="../sources/windows/MainWindow.ui" line="394"/>
         <source>&amp;New</source>
         <translation>&amp;Nuovo</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="384"/>
+        <location filename="../sources/windows/MainWindow.ui" line="397"/>
         <source>Create a new game</source>
         <translation>Crea un nuovo gioco</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="392"/>
+        <location filename="../sources/windows/MainWindow.ui" line="405"/>
         <source>&amp;Load</source>
         <translation>&amp;Carica</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="395"/>
+        <location filename="../sources/windows/MainWindow.ui" line="408"/>
         <source>Load a game</source>
         <translation>Carica un gioco</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="403"/>
+        <location filename="../sources/windows/MainWindow.ui" line="416"/>
         <source>&amp;Save</source>
         <translation>&amp;Salva</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="406"/>
+        <location filename="../sources/windows/MainWindow.ui" line="419"/>
         <source>Save the current game</source>
         <translation>Salva il gioco corrente</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="414"/>
+        <location filename="../sources/windows/MainWindow.ui" line="427"/>
         <source>S&amp;ave as</source>
         <translation>S&amp;alva come</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="417"/>
+        <location filename="../sources/windows/MainWindow.ui" line="430"/>
         <source>Save the current game in a new file</source>
         <translation>Salva il gioco corrente in un nuovo file</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="425"/>
+        <location filename="../sources/windows/MainWindow.ui" line="438"/>
         <source>&amp;Quit</source>
         <translation>Esc&amp;i</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="428"/>
+        <location filename="../sources/windows/MainWindow.ui" line="441"/>
         <source>Exit the application</source>
         <translation>Esci dall&apos;applicazione</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="436"/>
+        <location filename="../sources/windows/MainWindow.ui" line="449"/>
         <source>About &amp;GM-Assistant</source>
         <translation>A proposito di &amp;GM-Assistant</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="439"/>
+        <location filename="../sources/windows/MainWindow.ui" line="452"/>
         <source>Display information about GM-Assistant</source>
         <translation>Mostra informazioni riguardo GM-Assistant</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="447"/>
+        <location filename="../sources/windows/MainWindow.ui" line="460"/>
         <source>&amp;Reload</source>
         <translation>&amp;Ricarica</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="450"/>
+        <location filename="../sources/windows/MainWindow.ui" line="463"/>
         <source>Reload the current game</source>
         <translation>Ricarica il gioco corrente</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="458"/>
+        <location filename="../sources/windows/MainWindow.ui" line="471"/>
         <source>R&amp;ecent</source>
         <translation>R&amp;ecente</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="461"/>
+        <location filename="../sources/windows/MainWindow.ui" line="474"/>
         <source>Load a recently opened game</source>
         <translation>Carica un gioco aperto di recente</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="472"/>
+        <location filename="../sources/windows/MainWindow.ui" line="485"/>
         <source>&amp;Full</source>
         <translation>&amp;Completo</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="475"/>
+        <location filename="../sources/windows/MainWindow.ui" line="488"/>
         <source>Tools shown: Plot, Notes, Characters, History, Music and Sound effects</source>
         <translation>Strumenti visualizzati: Trama, Appunti, Personaggi, Cronologia, Musica ed Effetti sonori</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="486"/>
+        <location filename="../sources/windows/MainWindow.ui" line="499"/>
         <source>&amp;Music</source>
         <translation>&amp;Musica</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="489"/>
+        <location filename="../sources/windows/MainWindow.ui" line="502"/>
         <source>Tools shown: Music and Sound effects</source>
         <translation>Strumenti visualizzati: Musica ed Effetti sonori</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="500"/>
+        <location filename="../sources/windows/MainWindow.ui" line="513"/>
         <source>&amp;Simple</source>
         <translation>&amp;Semplice</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="503"/>
+        <location filename="../sources/windows/MainWindow.ui" line="516"/>
         <source>Tools shown: Plot, Music and Sound effects</source>
         <translation>Strumenti visualizzati: Trama, Musica ed Effetti sonori</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="514"/>
+        <location filename="../sources/windows/MainWindow.ui" line="527"/>
         <source>&amp;Design</source>
         <translatorcomment>What is the context here?</translatorcomment>
         <translation>&amp;Progettazione</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="517"/>
+        <location filename="../sources/windows/MainWindow.ui" line="530"/>
         <source>Tools shown: Plot, Characters and Notes</source>
         <translation>Strumenti visualizzati: Trama, Personaggi e Appunti</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="528"/>
+        <location filename="../sources/windows/MainWindow.ui" line="541"/>
         <source>&amp;No Music</source>
         <translation>&amp;Niente musica</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="531"/>
+        <location filename="../sources/windows/MainWindow.ui" line="544"/>
         <source>Tools shown: Plot, Characters, History and Notes</source>
         <translation>Strumenti visualizzati: Trama, Personaggi, Cronologia e Appunti</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="539"/>
+        <location filename="../sources/windows/MainWindow.ui" line="552"/>
         <source>&amp;Undo</source>
         <translation>&amp;Annulla</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="542"/>
+        <location filename="../sources/windows/MainWindow.ui" line="555"/>
         <source>Undo the last modification</source>
         <translation>Annulla l&apos;ultima modifica</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="550"/>
+        <location filename="../sources/windows/MainWindow.ui" line="563"/>
         <source>&amp;Redo</source>
         <translation>&amp;Ripeti</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="553"/>
+        <location filename="../sources/windows/MainWindow.ui" line="566"/>
         <source>Redo the last undone modification</source>
         <translation>Ripeti l&apos;ultima modifica annullata</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="561"/>
+        <location filename="../sources/windows/MainWindow.ui" line="574"/>
         <source>&amp;Dice simulator</source>
         <translation>&amp;Simulatore di dadi</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="564"/>
+        <location filename="../sources/windows/MainWindow.ui" line="577"/>
         <source>Throw virtual dices</source>
         <translation>Tira i dadi virtuali</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="572"/>
+        <location filename="../sources/windows/MainWindow.ui" line="585"/>
         <source>&amp;Combat manager</source>
         <translation>&amp;Gestore di combattimento</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="575"/>
+        <location filename="../sources/windows/MainWindow.ui" line="588"/>
         <source>Manage round per round combats</source>
         <translation>Gestisci i combattimenti round per round</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="586"/>
+        <location filename="../sources/windows/MainWindow.ui" line="599"/>
         <source>&amp;English</source>
         <translatorcomment>Is it required? The French file has no entry here</translatorcomment>
         <translation>&amp;Inglese</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="591"/>
+        <location filename="../sources/windows/MainWindow.ui" line="604"/>
         <source>&amp;Metadata</source>
         <translation>&amp;Metadati</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="594"/>
+        <location filename="../sources/windows/MainWindow.ui" line="607"/>
         <source>Edit the game metadata</source>
         <translation>Modifica i metadati del gioco</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="602"/>
+        <location filename="../sources/windows/MainWindow.ui" line="615"/>
         <source>About &amp;Qt</source>
         <translation>A proposito di &amp;Qt</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.ui" line="605"/>
+        <location filename="../sources/windows/MainWindow.ui" line="618"/>
         <source>Display information about Qt</source>
         <translation>Informazioni su Qt</translation>
     </message>
     <message>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="96"/>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="110"/>
-        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="495"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="306"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="312"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="353"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="398"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="512"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="551"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="564"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="570"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="880"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="97"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="111"/>
+        <location filename="../sources/widgets/QCustomTreeWidget.cpp" line="537"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="316"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="322"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="363"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="408"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="523"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="562"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="575"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="581"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="888"/>
         <source>Error</source>
         <translation>Errore</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="295"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="305"/>
         <source>Select the file to open</source>
         <translation>Seleziona il file da aprire</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="295"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="305"/>
         <source>GM-Assistant files (*.gms *.gma);;XML files (*.xml)</source>
         <translation>File GM-Assistant (*.gms *.gma);;File XML (*.xml)</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="312"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="570"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="322"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="581"/>
         <source>The game cannot be loaded correctly for the following reason:</source>
         <translation>Il gioco non può essere caricato correttamente per i seguenti motivi:</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="312"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="570"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="322"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="581"/>
         <source>The game will be loaded anyway, but some features might not work properly.</source>
         <translation>Il gioco sarà caricato comunque, ma alcuni aspetti potrebbero non funzionare correttamente.</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="322"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="341"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="578"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="332"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="351"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="589"/>
         <source>Warning</source>
         <translation>Attenzione</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="322"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="578"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="332"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="589"/>
         <source>The syntax of the game you have just loaded is not rigourously correct. Would you like to fix it now?</source>
         <translation>La sintassi del gioco che hai appena caricato non è rigorosamente corretta. Vuoi correggerla ora?</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="341"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="351"/>
         <source>The game you want to save does not use the latest version of GM-Assistant files. Do you want to update it? If no, some features may not be saved properly.</source>
         <translation>Il gioco che vuoi salvare non utilizza la versione più recente di GM-Assistant. Vuoi aggiornarlo? Se no, alcuni aspetti potrebbero non essere salvati correttamente.</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="365"/>
-        <source>GM-Assistant files (1.2) (*.gms)</source>
-        <translation>File GM-Assistant (1.2) (*.gms)</translation>
+        <location filename="../sources/windows/MainWindow.cpp" line="375"/>
+        <source>GM-Assistant files (*.gms)</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="368"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="378"/>
         <source>;;GM-Assistant files (1.1) (*.gma);;GM-Assistant files (1.0) (*.xml)</source>
         <translation>;;File GM-Assistant (1.1) (*.gma);;File GM-Assistant (1.0) (*.xml)</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="370"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="380"/>
         <source>Select the file to save</source>
         <translation>Seleziona il file da salvare</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="458"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="469"/>
         <source>&amp;Resume</source>
         <translation>&amp;Riprendi</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="464"/>
-        <location filename="../sources/windows/MainWindow.cpp" line="940"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="475"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="948"/>
         <source>&amp;Pause</source>
         <translation>&amp;Pausa</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="512"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="523"/>
         <source>Unable to play the file</source>
         <translation>Impossibile riprodurre il file</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="551"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="562"/>
         <source>The file &quot;%1&quot; does not exist.</source>
         <translation>Il file &quot;%1&quot; non esiste.</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="735"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="746"/>
         <source>New game</source>
         <translation>Nuovo gioco</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="827"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="835"/>
         <source>Confirmation</source>
         <translation>Conferma</translation>
     </message>
     <message>
-        <location filename="../sources/windows/MainWindow.cpp" line="827"/>
+        <location filename="../sources/windows/MainWindow.cpp" line="835"/>
         <source>The current game has been modified since the last save. If you continue, unsaved changes will be discarded.</source>
         <translation>Il gioco corrente è stato modificato dall&apos;ultimo salvataggio. Se continui, le modifiche non salvate andranno perse.</translation>
     </message>
@@ -987,6 +1031,39 @@
         <translation>Gioco di ruolo</translation>
     </message>
 </context>
+<context>
+    <name>renameNoteDialog</name>
+    <message>
+        <location filename="../sources/windows/RenameNoteDialog.ui" line="17"/>
+        <source>New title</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/RenameNoteDialog.ui" line="29"/>
+        <source>Title of the note:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/RenameNoteDialog.ui" line="41"/>
+        <source>&amp;Validate</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/RenameNoteDialog.ui" line="52"/>
+        <source>&amp;Cancel</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/RenameNoteDialog.cpp" line="41"/>
+        <source>Incomplete data</source>
+        <translation type="unfinished">Dati incompleti</translation>
+    </message>
+    <message>
+        <location filename="../sources/windows/RenameNoteDialog.cpp" line="41"/>
+        <source>You must fill the title before validating.</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>selectCharacterDialog</name>
     <message>
@@ -1015,12 +1092,12 @@
         <translation>Personaggi coinvolti</translation>
     </message>
     <message>
-        <location filename="../sources/windows/SelectCharacterDialog.ui" line="81"/>
+        <location filename="../sources/windows/SelectCharacterDialog.ui" line="74"/>
         <source>&amp;Up</source>
         <translation>&amp;Su</translation>
     </message>
     <message>
-        <location filename="../sources/windows/SelectCharacterDialog.ui" line="92"/>
+        <location filename="../sources/windows/SelectCharacterDialog.ui" line="85"/>
         <source>&amp;Down</source>
         <translation>&amp;Giù</translation>
     </message>

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in second set of .debs but not in first

-rw-r--r--  root/root   /usr/lib/debug/.build-id/52/65cb5dafb8717e3d24da094c9bb12834a43583.debug
-rw-r--r--  root/root   /usr/share/games/gm-assistant/CHANGELOG

Files in first set of .debs but not in second

-rw-r--r--  root/root   /usr/lib/debug/.build-id/49/c16b29c11f046179a60c82565351e65c23ab83.debug

Control files of package gm-assistant: lines which differ (wdiff format)

  • Depends: libc6 (>= 2.14), 2.34), libgcc-s1 (>= 3.0), libpocofoundation80 (>= 1.11.0), libpocoxml80 (>= 1.11.0), libpocozip80 (>= 1.11.0), libqt5core5a (>= 5.15.1), libqt5gui5 (>= 5.8.0) | libqt5gui5-gles (>= 5.8.0), libqt5multimedia5 (>= 5.6.0~beta), libqt5svg5 (>= 5.6.0~beta), libqt5widgets5 (>= 5.14.1), libstdc++6 (>= 11)

Control files of package gm-assistant-dbgsym: lines which differ (wdiff format)

  • Build-Ids: 49c16b29c11f046179a60c82565351e65c23ab83 5265cb5dafb8717e3d24da094c9bb12834a43583

No differences were encountered between the control files of package gm-assistant-doc

More details

Full run details