r17826 by craig - #11032: Cezary : Add footnotes and marks features

scribus-commit scribus-commit at lists.scribus.net
Sat Oct 27 15:56:36 UTC 2012


Author: craig
Date: Sat Oct 27 15:56:36 2012
New Revision: 17826

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=17826
Log:
#11032: Cezary : Add footnotes and marks features

Modified:
    trunk/Scribus/scribus/CMakeLists.txt
    trunk/Scribus/scribus/actionmanager.cpp
    trunk/Scribus/scribus/canvas.cpp
    trunk/Scribus/scribus/canvas.h
    trunk/Scribus/scribus/canvasmode_edit.cpp
    trunk/Scribus/scribus/canvasmode_normal.cpp
    trunk/Scribus/scribus/documentchecker.cpp
    trunk/Scribus/scribus/fonts/scface.cpp
    trunk/Scribus/scribus/pageitem.cpp
    trunk/Scribus/scribus/pageitem.h
    trunk/Scribus/scribus/pageitem_textframe.cpp
    trunk/Scribus/scribus/pageitem_textframe.h
    trunk/Scribus/scribus/pagestructs.h
    trunk/Scribus/scribus/plugins/fileloader/scribus150format/scribus150format.cpp
    trunk/Scribus/scribus/plugins/fileloader/scribus150format/scribus150format.h
    trunk/Scribus/scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp
    trunk/Scribus/scribus/plugins/gettext/textfilter/textfilter.cpp
    trunk/Scribus/scribus/plugins/scriptplugin/scriptercore.cpp
    trunk/Scribus/scribus/scribus.cpp
    trunk/Scribus/scribus/scribus.h
    trunk/Scribus/scribus/scribusdoc.cpp
    trunk/Scribus/scribus/scribusdoc.h
    trunk/Scribus/scribus/scribusstructs.h
    trunk/Scribus/scribus/scribusview.cpp
    trunk/Scribus/scribus/sctextstruct.cpp
    trunk/Scribus/scribus/sctextstruct.h
    trunk/Scribus/scribus/serializer.h
    trunk/Scribus/scribus/tablecell.cpp
    trunk/Scribus/scribus/text/storytext.cpp
    trunk/Scribus/scribus/text/storytext.h
    trunk/Scribus/scribus/ui/charselect.cpp
    trunk/Scribus/scribus/ui/checkDocument.cpp
    trunk/Scribus/scribus/ui/contextmenu.cpp
    trunk/Scribus/scribus/ui/loremipsum.cpp
    trunk/Scribus/scribus/undomanager.cpp
    trunk/Scribus/scribus/undomanager.h
    trunk/Scribus/scribus/undostate.h
    trunk/Scribus/scribus/util.cpp
    trunk/Scribus/scribus/util.h
    trunk/Scribus/scribus/util_text.cpp
    trunk/Scribus/scribus/util_text.h

Modified: trunk/Scribus/scribus/CMakeLists.txt
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/CMakeLists.txt
==============================================================================
--- trunk/Scribus/scribus/CMakeLists.txt (original)
+++ trunk/Scribus/scribus/CMakeLists.txt Sat Oct 27 15:56:36 2012
@@ -85,11 +85,18 @@
   ui/inserttablerowsdialog.ui
   ui/latexeditor.ui
   ui/newmarginwidgetbase.ui
+ui/mark2item.ui
+ui/mark2mark.ui
+ui/markanchor.ui
+ui/marknote.ui
+ui/markvariabletext.ui
+ui/marksmanager.ui
   ui/measurementsbase.ui
   ui/multipleduplicate.ui
   ui/multiprogressdialog.ui
   ui/nftdialog.ui
   ui/nftwidget.ui
+ui/notesstyleseditor.ui
   ui/pageitemattributes.ui
   ui/pagepalette_pagesbase.ui
   ui/pagepalette_masterpagesbase.ui
@@ -209,7 +216,9 @@
   latexhelpers.h
   loadsaveplugin.h
   menumanager.h
+marks.h
   navigator.h
+notesstyles.h
   observable.h
   pageitem.h
   pageitem_arc.h
@@ -225,6 +234,7 @@
   pageitem_symbol.h
   pageitem_table.h
   pageitem_textframe.h
+pageitem_noteframe.h
   pageitempointer.h
   pdf_analyzer.h
   pdflib.h
@@ -317,6 +327,13 @@
   ui/latexeditor.h
   ui/layers.h
   ui/loremipsum.h
+ui/MarkInsertDlg.h
+ui/mark2item.h
+ui/mark2mark.h
+ui/markanchor.h
+ui/marknote.h
+ui/markvariabletext.h
+ui/marksmanager.h
   ui/margindialog.h
   ui/marginpresetlayout.h
   ui/marginwidget.h
@@ -332,6 +349,7 @@
   ui/nftdialog.h
   ui/nftwidget.h
   ui/nodeeditpalette.h
+ui/notesstyleseditor.h
   ui/oneclick.h
   ui/outlinepalette.h
   ui/pageitemattributes.h
@@ -565,6 +583,7 @@
   nftrcreader.cpp
   nftsettings.cpp
   nfttemplate.cpp
+notesstyles.cpp
   pageitem.cpp
   pageitem_arc.cpp
   pageitem_group.cpp
@@ -579,6 +598,7 @@
   pageitem_symbol.cpp
   pageitem_table.cpp
   pageitem_textframe.cpp
+pageitem_noteframe.cpp
   pageitempointer.cpp
   pagesize.cpp
   pdf_analyzer.cpp
@@ -751,6 +771,12 @@
   ui/linecombo.cpp
   ui/linkbutton.cpp
   ui/loremipsum.cpp
+ui/mark2item.cpp
+ui/mark2mark.cpp
+ui/markanchor.cpp
+ui/marknote.cpp
+ui/markvariabletext.cpp
+ui/marksmanager.cpp
   ui/margindialog.cpp
   ui/marginpresetlayout.cpp
   ui/marginwidget.cpp
@@ -766,6 +792,7 @@
   ui/nftdialog.cpp
   ui/nftwidget.cpp
   ui/nodeeditpalette.cpp
+ui/notesstyleseditor.cpp
   ui/oneclick.cpp
   ui/outlinepalette.cpp
   ui/pageitemattributes.cpp

Modified: trunk/Scribus/scribus/actionmanager.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/actionmanager.cpp
==============================================================================
--- trunk/Scribus/scribus/actionmanager.cpp (original)
+++ trunk/Scribus/scribus/actionmanager.cpp Sat Oct 27 15:56:36 2012
@@ -240,8 +240,14 @@
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 	name="editJavascripts";
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	name="editMarks";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	name="editNotesStyles";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 
 	(*scrActions)["editStyles"]->setToggleAction(true);
+	(*scrActions)["editMarks"]->setToggleAction(true);
+	(*scrActions)["editNotesStyles"]->setToggleAction(true);
 
 	connect( (*scrActions)["editUndoAction"], SIGNAL(triggeredData(int)) , undoManager, SLOT(undo(int)) );
 	connect( (*scrActions)["editRedoAction"], SIGNAL(triggeredData(int)) , undoManager, SLOT(redo(int)) );
@@ -542,10 +548,45 @@
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 	(*scrActions)["stickyTools"]->setToggleAction(true);
 
+	//Marks
+	name="insertMarkAnchor";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarkVariableText";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarkItem";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMark2Mark";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarkNote";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+//	name="insertMarkIndex";
+//	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+//	(*scrActions)[name]->setEnabled(true);
+	name="editMark";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(false);
+	name="itemUpdateMarks";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(false);
+
 	connect( (*scrActions)["insertFrame"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertFrame()) );
 	connect( (*scrActions)["insertGlyph"], SIGNAL(triggered()), mainWindow, SLOT(slotCharSelect()) );
 	connect( (*scrActions)["insertSampleText"], SIGNAL(triggered()), mainWindow, SLOT(insertSampleText()) );
 	connect( (*scrActions)["stickyTools"], SIGNAL(triggered()), mainWindow, SLOT(ToggleStickyTools()) );
+
+	connect( (*scrActions)["insertMarkAnchor"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkAnchor()) );
+	connect( (*scrActions)["insertMarkVariableText"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkVariableText()) );
+	connect( (*scrActions)["insertMarkItem"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkItem()) );
+	connect( (*scrActions)["insertMark2Mark"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMark2Mark()) );
+	connect( (*scrActions)["insertMarkNote"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkNote()) );
+//	connect( (*scrActions)["insertMarkIndex"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkIndex()) );
+	connect( (*scrActions)["editMark"], SIGNAL(triggered()), mainWindow, SLOT(slotEditMark()) );
+	connect( (*scrActions)["itemUpdateMarks"], SIGNAL(triggered()), mainWindow, SLOT(slotUpdateMarks()) );
 }
 
 void ActionManager::initPageMenuActions()
@@ -1413,6 +1454,8 @@
 //	(*scrActions)["editPatterns"]->setTexts( tr("Patterns..."));
 //	(*scrActions)["editGradients"]->setTexts( tr("Gradients..."));
 	(*scrActions)["editStyles"]->setTexts( tr("S&tyles..."));
+	(*scrActions)["editMarks"]->setTexts( tr("Marks..."));
+	(*scrActions)["editNotesStyles"]->setTexts( tr("Notes Styles..."));
 	(*scrActions)["editMasterPages"]->setTexts( tr("&Master Pages..."));
 	(*scrActions)["editJavascripts"]->setTexts( tr("&JavaScripts..."));
 
@@ -1508,6 +1551,14 @@
 	(*scrActions)["insertGlyph"]->setTexts( tr("&Glyph..."));
 	(*scrActions)["insertSampleText"]->setTexts( tr("Sample Text"));
 	(*scrActions)["stickyTools"]->setTexts( tr("Sticky Tools"));
+	(*scrActions)["insertMarkAnchor"]->setTexts( tr("Anchor Mark"));
+	(*scrActions)["insertMarkVariableText"]->setTexts( tr("Variable Text"));
+	(*scrActions)["insertMarkItem"]->setTexts( tr("Reference to Item"));
+	(*scrActions)["insertMark2Mark"]->setTexts( tr("Reference to Mark"));
+	(*scrActions)["insertMarkNote"]->setTexts( tr("Foot/Endnote"));
+//	(*scrActions)["insertMarkIndex"]->setTexts( tr("Index entry"));
+	(*scrActions)["editMark"]->setTexts( tr("Edit Mark"));
+	(*scrActions)["itemUpdateMarks"]->setTexts( tr("Update Marks"));
 
 	//Page menu
 	(*scrActions)["pageInsert"]->setTexts( tr("&Insert..."));
@@ -1900,6 +1951,8 @@
 		<< "editReplaceColors"
 //		<< "editPatterns"
 		<< "editStyles"
+		<< "editMarks"
+		<< "editNotesStyles"
 		<< "editMasterPages"
 		<< "editJavascripts";
 	//Style
@@ -2008,7 +2061,15 @@
 		<< "toolsInsertRenderFrame"
 		<< "stickyTools"
 		<< "insertGlyph"
-		<< "insertSampleText";
+		<< "insertSampleText"
+		<< "insertMarkAnchor"
+		<< "insertMarkVariableText"
+		<< "insertMarkItem"
+		<< "insertMark2Mark"
+		<< "insertMarkNote"
+		<< "insertMarkIndex"
+		<< "editMark"
+		<< "itemUpdateMarks";
 
 	itmenu->second
 		<< "unicodeSoftHyphen"

Modified: trunk/Scribus/scribus/canvas.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/canvas.cpp
==============================================================================
--- trunk/Scribus/scribus/canvas.cpp (original)
+++ trunk/Scribus/scribus/canvas.cpp Sat Oct 27 15:56:36 2012
@@ -1035,7 +1035,10 @@
 					{
 						DrawMasterItems(painter, m_doc->Pages->at(a), layer, QRect(clipx, clipy, clipw, cliph));
 					}
-					DrawPageItems(painter, layer, QRect(clipx, clipy, clipw, cliph));
+					//first pass draws all except notes frames
+					DrawPageItems(painter, layer, QRect(clipx, clipy, clipw, cliph), false);
+					//seconf only for notes frames
+					DrawPageItems(painter, layer, QRect(clipx, clipy, clipw, cliph), true);
 				}
 			}
 		}
@@ -1076,7 +1079,10 @@
 				for (int layerLevel = 0; layerLevel < layerCount; ++layerLevel)
 				{
 					m_doc->Layers.levelToLayer(layer, layerLevel);
-					DrawPageItems(painter, layer, QRect(clipx, clipy, clipw, cliph));
+					//first pass draws all except notes frames
+					DrawPageItems(painter, layer, QRect(clipx, clipy, clipw, cliph), false);
+					//second pass draw only notes frames
+					DrawPageItems(painter, layer, QRect(clipx, clipy, clipw, cliph), true);
 				}
 			}
 		}
@@ -1445,7 +1451,7 @@
 /**
   draws page items contained in a specific Layer
  */
-void Canvas::DrawPageItems(ScPainter *painter, ScLayer& layer, QRect clip)
+void Canvas::DrawPageItems(ScPainter *painter, ScLayer& layer, QRect clip, bool notesFramesPass)
 {
 	if ((m_viewMode.previewMode) && (!layer.isPrintable))
 		return;
@@ -1466,9 +1472,34 @@
 	int docCurrPageNo=static_cast<int>(m_doc->currentPageNumber());
 	if ((layerCount > 1) && ((layer.blendMode != 0) || (layer.transparency != 1.0)) && (!layer.outlineMode))
 		painter->beginLayer(layer.transparency, layer.blendMode);
+
+	//if notes are used
+	//then we must be sure that text frames are valid and all notes frames are created before we start drawing
+	if (!notesFramesPass && !m_doc->notesList().isEmpty())
+	{
 	for (int it = 0; it < m_doc->Items->count(); ++it)
 	{
 		currItem = m_doc->Items->at(it);
+			if ( !currItem->isTextFrame()
+				|| currItem->isNoteFrame()
+				|| !currItem->invalid
+				|| (currItem->LayerID != layer.ID)
+				|| (m_viewMode.previewMode && !currItem->printEnabled())
+				|| (m_viewMode.viewAsPreview && (!currItem->printEnabled()))
+				|| (m_doc->masterPageMode() && ((currItem->OwnPage != -1) && (currItem->OwnPage != docCurrPageNo)))
+				|| ((!m_doc->masterPageMode() && !currItem->OnMasterPage.isEmpty()) && (currItem->OnMasterPage != m_doc->currentPage()->pageName())))
+				continue;
+			if (cullingArea.intersects(currItem->getBoundingRect().adjusted(0.0, 0.0, 1.0, 1.0)))
+				currItem->layout();
+		}
+	}
+	for (int it = 0; it < m_doc->Items->count(); ++it)
+	{
+		currItem = m_doc->Items->at(it);
+		if (notesFramesPass && !currItem->isNoteFrame())
+			continue;
+		if (!notesFramesPass && currItem->isNoteFrame())
+			continue;
 		if (currItem->LayerID != layer.ID)
 			continue;
 		if ((m_viewMode.previewMode) && (!currItem->printEnabled()))

Modified: trunk/Scribus/scribus/canvas.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/canvas.h
==============================================================================
--- trunk/Scribus/scribus/canvas.h (original)
+++ trunk/Scribus/scribus/canvas.h Sat Oct 27 15:56:36 2012
@@ -195,7 +195,8 @@
 	void setPreviewVisual(int mode);
 	
 	void DrawMasterItems(ScPainter *painter, ScPage *page, ScLayer& layer, QRect clip);
-	void DrawPageItems(ScPainter *painter, ScLayer& layer, QRect clip);
+	//notesFramesPass determine if notes frames are drawed or not
+	void DrawPageItems(ScPainter *painter, ScLayer& layer, QRect clip, bool notesFramesPass);
 	virtual void paintEvent ( QPaintEvent * p );
 	void displayXYHUD(QPoint m);
 	void displayCorrectedXYHUD(QPoint m, double x, double y);

Modified: trunk/Scribus/scribus/canvasmode_edit.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/canvasmode_edit.cpp
==============================================================================
--- trunk/Scribus/scribus/canvasmode_edit.cpp (original)
+++ trunk/Scribus/scribus/canvasmode_edit.cpp Sat Oct 27 15:56:36 2012
@@ -315,6 +315,11 @@
 				currItem->itemText.extendSelection(start, stop);
 				currItem->itemText.setCursorPosition(stop);
 			}
+			else if ((currItem->itemText.cursorPosition() < currItem->itemText.length()) && (currItem->itemText.item(currItem->itemText.cursorPosition())->mark != NULL))
+			{	//invoke edit marker dialog
+				m_ScMW->slotEditMark();
+				return;
+			}
 			else
 			{	//Double click in a frame to select a word
 				oldCp = currItem->itemText.cursorPosition();

Modified: trunk/Scribus/scribus/canvasmode_normal.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/canvasmode_normal.cpp
==============================================================================
--- trunk/Scribus/scribus/canvasmode_normal.cpp (original)
+++ trunk/Scribus/scribus/canvasmode_normal.cpp Sat Oct 27 15:56:36 2012
@@ -241,6 +241,9 @@
 			{
 				m_view->requestMode(modeEdit);
 				m_view->slotSetCurs(m->globalPos().x(), m->globalPos().y());
+				//used for updating Notes Styles Editor and menu actions for marks
+				//if cursor is in mark`s place
+				m_ScMW->setTBvals(currItem);
 				//CB ignore the double click and go with a single one
 				//if we werent in mode edit before.
 				//unsure if this is correct, but its ok given we had no
@@ -716,7 +719,11 @@
 					if(currItem->asLine())
 						qApp->changeOverrideCursor(QCursor(Qt::SizeAllCursor));
 					else if(!currItem->locked() && !currItem->sizeLocked())
+					{
+						if ((!currItem->sizeHLocked() && !currItem->sizeVLocked()) || (currItem->sizeHLocked() && (how == 5 || how == 8))
+							|| (currItem->sizeVLocked() && (how == 6 || how == 7)))
 						setResizeCursor(how, currItem->rotation());
+				}
 				}
 				else if (how == 0)
 					qApp->changeOverrideCursor(QCursor(Qt::OpenHandCursor));
@@ -957,7 +964,7 @@
 			while(underItem)
 			{
 				if(underItem->asTextFrame())
-					underItem->asTextFrame()->invalidateLayout();
+					underItem->asTextFrame()->invalidateLayout(false);
 				else
 					underItem->invalidateLayout();
 				

Modified: trunk/Scribus/scribus/documentchecker.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/documentchecker.cpp
==============================================================================
--- trunk/Scribus/scribus/documentchecker.cpp (original)
+++ trunk/Scribus/scribus/documentchecker.cpp Sat Oct 27 15:56:36 2012
@@ -98,6 +98,10 @@
 		if (layerError.count() != 0)
 			currDoc->docLayerErrors.insert(ll.ID, layerError);
 	}
+
+	//update all marks references and check if that changes anything in doc
+	currDoc->setNotesChanged(currDoc->updateMarks(true));
+
 	QList<PageItem*> allItems;
 	uint masterItemsCount = currDoc->MasterItems.count();
 	for (uint i = 0; i < masterItemsCount; ++i)

Modified: trunk/Scribus/scribus/fonts/scface.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/fonts/scface.cpp
==============================================================================
--- trunk/Scribus/scribus/fonts/scface.cpp (original)
+++ trunk/Scribus/scribus/fonts/scface.cpp Sat Oct 27 15:56:36 2012
@@ -343,7 +343,7 @@
 	if (ch == SpecialChars::LINEBREAK || ch == SpecialChars::PARSEP 
 		|| ch == SpecialChars::FRAMEBREAK || ch == SpecialChars::COLBREAK 
 		|| ch == SpecialChars::TAB || ch == SpecialChars::SHYPHEN
-		 || ch == SpecialChars::ZWSPACE || ch == SpecialChars::ZWNBSPACE)
+		 || ch == SpecialChars::ZWSPACE || ch == SpecialChars::ZWNBSPACE || ch==SpecialChars::OBJECT)
 		return CONTROL_GLYPHS + ch.unicode();
 	else if (ch == SpecialChars::NBSPACE)
 		return  m->char2CMap(QChar(' '));

Modified: trunk/Scribus/scribus/pageitem.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/pageitem.cpp
==============================================================================
--- trunk/Scribus/scribus/pageitem.cpp (original)
+++ trunk/Scribus/scribus/pageitem.cpp Sat Oct 27 15:56:36 2012
@@ -35,18 +35,22 @@
 #include <QMessageBox>
 #include <QPolygon>
 #include <cassert>
+#include <sstream>
 #include <QDebug>
 
 #include "canvas.h"
 #include "cmsettings.h"
 #include "colorblind.h"
 #include "commonstrings.h"
+#include "desaxe/saxXML.h"
+#include "marks.h"
 
 #include "pageitem_group.h"
 #include "pageitem_regularpolygon.h"
 #include "pageitem_arc.h"
 #include "pageitem_spiral.h"
 #include "pageitem_textframe.h"
+#include "pageitem_noteframe.h"
 #include "pageitem_latexframe.h"
 #include "prefsmanager.h"
 
@@ -244,6 +248,8 @@
 	m_ImageIsFlippedV(other.m_ImageIsFlippedV),
 	m_Locked(other.m_Locked),
 	m_SizeLocked(other.m_SizeLocked),
+	m_SizeHLocked(other.m_SizeHLocked),
+	m_SizeVLocked(other.m_SizeVLocked),
 	textFlowModeVal(other.textFlowModeVal),
 	pageItemAttributes(other.pageItemAttributes),
 	m_PrintEnabled(other.m_PrintEnabled),
@@ -382,6 +388,8 @@
 	m_ImageIsFlippedV(0),
 	m_Locked(false),
 	m_SizeLocked(false),
+	m_SizeHLocked(false),
+	m_SizeVLocked(false),
 	textFlowModeVal(TextFlowDisabled)
 {
 	Parent = NULL;
@@ -828,6 +836,32 @@
 	isInlineImage = false;
 }
 
+PageItem::~PageItem()
+{
+	if (tempImageFile != NULL)
+		delete tempImageFile;
+	//remove marks
+
+	if (isTextFrame())
+	{
+		if (!asTextFrame()->isInChain() && itemText.length() >0)
+		{
+			for (int pos=0; pos < itemText.length(); ++pos)
+			{
+				if (itemText.item(pos)->hasMark())
+				{
+					Mark* mrk = itemText.item(pos)->mark;
+					m_Doc->eraseMark(mrk);
+				}
+			}
+		}
+	}
+//		if (isWeld())
+//			unWeldFromMaster(true);
+//		if (isWelded())
+//			unWeldChild();
+}
+
 void PageItem::setXPos(const double newXPos, bool drawingOnly)
 {
 	Xpos = newXPos;
@@ -884,8 +918,8 @@
 	}
 	if (drawingOnly || m_Doc->isLoading())
 		return;
+	moveWelded(dX, dY);
 	checkChanges();
-	moveWelded(dX, dY);
 }
 
 void PageItem::setWidth(const double newWidth)
@@ -947,8 +981,8 @@
 	Rot = newRotation;
 	if (drawingOnly || m_Doc->isLoading())
 		return;
+	rotateWelded(dR, oldRot);
 	checkChanges();
-	rotateWelded(dR, oldRot);
 }
 
 void PageItem::rotateBy(const double dR)
@@ -2272,6 +2306,13 @@
 		else
 			return "%";
 	}
+	//check for marks
+	else if (ch == SpecialChars::OBJECT)
+	{
+		ScText* hl = itemText.item(base);
+		if ((hl->mark != NULL) && !hl->mark->isType(MARKAnchorType) && !hl->mark->isType(MARKIndexType))
+			chstr = hl->mark->getString();
+	}
 	return chstr;
 }
 
@@ -2455,6 +2496,13 @@
 		{
 			points.resize(0);
 			points.addQuadPoint(0, -10, 0, -10, 0, -6, 0, -6);
+			stroke = true;
+		}
+		else if (glyph == SpecialChars::OBJECT.unicode())
+		{
+			//for showing marks entries as control chars
+			points.resize(0);
+			points.addQuadPoint(0, -8, 1, -8, 0, -6, 1, -6);
 			stroke = true;
 		}
 		else // ???
@@ -4624,27 +4672,47 @@
 {
 	if (oldHeight == Height && oldWidth == Width)
 		return;
-	if (UndoManager::undoEnabled())
+	bool doUndo = true;
+	if (isNoteFrame()
+		&& ((asNoteFrame()->isAutoHeight() && asNoteFrame()->isAutoWidth())
+			|| ((oldHeight == Height) && asNoteFrame()->isAutoWidth())
+			|| ((oldWidth == Width) && asNoteFrame()->isAutoHeight())))
+		doUndo = false;
+	if (doUndo && UndoManager::undoEnabled())
 	{
 		SimpleState *ss = new SimpleState(Um::Resize,
                            QString(Um::ResizeFromTo).arg(oldWidth).arg(oldHeight).arg(Width).arg(Height),
                                           Um::IResize);
+		if (!isNoteFrame() || !asNoteFrame()->isAutoWidth())
+		{
 		ss->set("OLD_WIDTH", oldWidth);
-		ss->set("OLD_HEIGHT", oldHeight);
 		ss->set("NEW_WIDTH", Width);
+		}
+		if (!isNoteFrame() || !asNoteFrame()->isAutoHeight())
+		{
+			ss->set("OLD_HEIGHT", oldHeight);
 		ss->set("NEW_HEIGHT", Height);
+		}
+		if (!isNoteFrame() || !asNoteFrame()->isAutoWelded())
+		{
 		ss->set("OLD_RXPOS", oldXpos);
 		ss->set("OLD_RYPOS", oldYpos);
 		ss->set("NEW_RXPOS", Xpos);
 		ss->set("NEW_RYPOS", Ypos);
+		}
 		ss->set("OLD_RROT", oldRot);
 		ss->set("NEW_RROT", Rot);
 		undoManager->action(this, ss);
 	}
+	if (!isNoteFrame() || !asNoteFrame()->isAutoWidth())
+		oldWidth = Width;
+	if (!isNoteFrame() || !asNoteFrame()->isAutoHeight())
+		oldHeight = Height;
+	if (!isNoteFrame() || !asNoteFrame()->isAutoWelded())
+	{
 	oldXpos = Xpos;
 	oldYpos = Ypos;
-	oldHeight = Height;
-	oldWidth = Width;
+	}
 	oldOwnPage = OwnPage;
 	oldRot = Rot;
 }
@@ -4660,14 +4728,23 @@
                                           Um::IRotate);
 		ss->set("OLD_ROT", oldRot);
 		ss->set("NEW_ROT", Rot);
+		if (!isNoteFrame() || !asNoteFrame()->isAutoWelded())
+		{
 		ss->set("OLD_RXPOS", oldXpos);
 		ss->set("OLD_RYPOS", oldYpos);
 		ss->set("NEW_RXPOS", Xpos);
 		ss->set("NEW_RYPOS", Ypos);
-		ss->set("OLD_RWIDTH", oldWidth);
+		}
+		if (!isNoteFrame() || !asNoteFrame()->isAutoHeight())
+		{
 		ss->set("OLD_RHEIGHT", oldHeight);
-		ss->set("NEW_RWIDTH", Width);
 		ss->set("NEW_RHEIGHT", Height);
+		}
+		if (!isNoteFrame() || !asNoteFrame()->isAutoWidth())
+		{
+			ss->set("NEW_RWIDTH", Width);
+			ss->set("OLD_RWIDTH", oldWidth);
+		}
 		undoManager->action(this, ss);
 	}
 	oldRot = Rot;
@@ -4751,7 +4828,7 @@
 			restoreStartArrowScale(ss, isUndo);
 		else if (ss->contains("IMAGE_ROTATION"))
 			restoreImageRotation(ss, isUndo);
-		else if (ss->contains("OLD_HEIGHT"))
+		else if (ss->contains("OLD_HEIGHT") || ss->contains("OLD_WIDTH"))
 			restoreResize(ss, isUndo);
 		else if (ss->contains("OLD_ROT"))
 			restoreRotate(ss, isUndo);
@@ -4881,6 +4958,8 @@
 			restoreArrow(ss, isUndo, true);
 		else if (ss->contains("END_ARROW"))
 			restoreArrow(ss, isUndo, false);
+		else if (ss->contains("PSTYLE"))
+			restorePStyle(ss, isUndo);
 		else if (ss->contains("CONVERT"))
 			restoreType(ss, isUndo);
 		else if (ss->contains("TEXTFLOW_OLDMODE"))
@@ -4983,22 +5062,6 @@
 	ContourLine = PoLine.copy();
 }
 
-void PageItem::restoreWeldItems(SimpleState *state, bool isUndo)
-{
-	if (isUndo)
-	{
-		unWeld();
-	}
-	else
-	{
-		ScItemState<PageItem*> *is = dynamic_cast<ScItemState<PageItem*>*>(state);
-		PageItem* wIt = is->getItem();
-		weldTo(wIt);
-	}
-	m_Doc->changed();
-	m_Doc->regionsChanged()->update(QRectF());
-}
-
 void PageItem::restoreUnWeldItem(SimpleState *state, bool isUndo)
 {
 	if (isUndo)
@@ -5023,6 +5086,22 @@
 	else
 	{
 		unWeld();
+	}
+	m_Doc->changed();
+	m_Doc->regionsChanged()->update(QRectF());
+}
+
+void PageItem::restoreWeldItems(SimpleState *state, bool isUndo)
+{
+	if (isUndo)
+	{
+		unWeld();
+	}
+	else
+	{
+		ScItemState<PageItem*> *is = dynamic_cast<ScItemState<PageItem*>*>(state);
+		PageItem* wIt = is->getItem();
+		weldTo(wIt);
 	}
 	m_Doc->changed();
 	m_Doc->regionsChanged()->update(QRectF());
@@ -6328,6 +6407,7 @@
 		itemText.select(start,text.length());
 		asTextFrame()->deleteSelectedTextFromFrame();
 	}
+	update();
 }
 
 void PageItem::restoreInsertFrameText(SimpleState *ss, bool isUndo)
@@ -6583,6 +6663,17 @@
 	else
 		setEndArrowIndex(i);
 }
+
+
+void PageItem::restorePStyle(SimpleState *state, bool isUndo)
+{
+	int styleid = state->getInt("OLD_STYLE");
+	if (!isUndo)
+		styleid = state->getInt("NEW_STYLE");
+	//will be done later with other text-undo:
+	//	m_Doc->chAbStyle(this, styleid);
+}
+
 
 // FIXME: This must go into class ScribusDoc!
 // For now we'll just make it independent of 'this' -- AV
@@ -7114,7 +7205,8 @@
 	pageItemAttributes=*map;
 }
 
-QString PageItem::generateUniqueCopyName(const QString originalName) const
+//if not `prependCopy` then string "Copy of" wil not be prepended
+QString PageItem::generateUniqueCopyName(const QString originalName, bool prependCopy) const
 {
 	if (!m_Doc->itemNameExists(originalName))
 		return originalName;
@@ -7122,7 +7214,7 @@
 	// Start embellishing the name until we get an acceptable unique name
 	// first we prefix `Copy of' if it's not already there
 	QString newname(originalName);
-	if (!originalName.startsWith( tr("Copy of")))
+	if (prependCopy && !originalName.startsWith( tr("Copy of")))
 		newname.prepend( tr("Copy of")+" ");
 
 	// See if the name prefixed by "Copy of " is free
@@ -9418,6 +9510,24 @@
 	}
 }
 
+PageItem* PageItem::firstInChain()
+{
+	Q_ASSERT(this != NULL);
+	PageItem* first = this;
+	while (first->prevInChain() != NULL)
+		first = first->prevInChain();
+	return first;
+}
+
+PageItem* PageItem::lastInChain()
+{
+	Q_ASSERT(this != NULL);
+	PageItem* last = this;
+	while (last->nextInChain() != NULL)
+		last = last->nextInChain();
+	return last;
+}
+
 QRect PageItem::getRedrawBounding(const double viewScale)
 {
 	int x = qRound(floor(BoundingX - Oldm_lineWidth / 2.0 - 5) * viewScale);
@@ -9766,7 +9876,8 @@
 	}
 }
 
-void PageItem::updateClip()
+//udateWelded determine if welded items should be updated as well (default behaviour)
+void PageItem::updateClip(bool updateWelded)
 {
 	if (m_Doc->appMode == modeDrawBezierLine)
 		return;
@@ -9876,9 +9987,30 @@
 					else
 						Clip = FlattenPath(PoLine, Segments);
 				}
+				if (updateWelded)
+				{
 				for (int i = 0 ; i < weldList.count(); i++)
 				{
 					weldingInfo wInf = weldList.at(i);
+						if (wInf.weldItem->isNoteFrame())
+						{
+							PageItem_NoteFrame* noteFrame = wInf.weldItem->asNoteFrame();
+							if (noteFrame->notesStyle()->isAutoWeldNotesFrames())
+							{
+								if (noteFrame->notesStyle()->isAutoNotesWidth())
+								{
+									if (noteFrame->width() != width())
+									{
+										noteFrame->setWidth(width());
+										noteFrame->updateClip();
+									}
+								}
+								noteFrame->setXYPos(xPos(),yPos() + height());
+								setWeldPoint(0, height(), noteFrame);
+								noteFrame->setWeldPoint(0,0, this);
+								continue;
+							}
+						}
 					FPointArray gr4;
 					FPoint wp = wInf.weldPoint;
 					gr4.addPoint(wp);
@@ -9889,6 +10021,7 @@
 					wInf.weldPoint = gr4.point(0);
 					weldList[i] = wInf;
 				}
+			}
 			}
 			OldB2 = width();
 			OldH2 = height();
@@ -9989,9 +10122,29 @@
 				Clip = FlattenPath(PoLine, Segments);
 			OldB2 = width();
 			OldH2 = height();
+			if (updateWelded)
+			{
 			for (int i = 0 ; i < weldList.count(); i++)
 			{
 				weldingInfo wInf = weldList.at(i);
+					if (wInf.weldItem->isNoteFrame())
+					{
+						PageItem_NoteFrame* noteFrame = wInf.weldItem->asNoteFrame();
+						if (noteFrame->notesStyle()->isAutoWeldNotesFrames())
+						{
+							if (noteFrame->notesStyle()->isAutoNotesWidth())
+							{
+								if (noteFrame->width() != width())
+								{
+									noteFrame->setWidth(width());
+									noteFrame->updateClip();
+								}
+							}
+							setWeldPoint(0, height(), noteFrame);
+							noteFrame->setWeldPoint(0,0, this);
+							continue;
+						}
+					}
 				FPointArray gr4;
 				FPoint wp = wInf.weldPoint;
 				gr4.addPoint(wp);
@@ -10003,6 +10156,7 @@
 				weldList[i] = wInf;
 			}
 		}
+		}
 		break;
 	}
 	updateGradientVectors();
@@ -10134,6 +10288,10 @@
 
 void PageItem::moveWelded(double DX, double DY, PageItem* except)
 {
+	if ((DX == 0) && (DY == 0))
+		return;
+	//do not save undo for auto-welded notes frames
+	UndoManager::instance()->setUndoEnabled(false);
 	for (int i = 0 ; i < weldList.count(); i++)
 	{
 		weldingInfo wInf = weldList.at(i);
@@ -10146,10 +10304,12 @@
 			pIt->moveWelded(DX, DY, this);
 		}
 	}
+	UndoManager::instance()->setUndoEnabled(true);
 }
 
 void PageItem::rotateWelded(double dR, double oldRot)
 {
+	UndoManager::instance()->setUndoEnabled(false);
 	QTransform ma;
 	ma.translate(xPos(), yPos());
 	ma.scale(1, 1);
@@ -10179,6 +10339,7 @@
 		pIt->setXYPos(lin.p2().x(), lin.p2().y());
 		pIt->rotateBy(dR);
 	}
+	UndoManager::instance()->setUndoEnabled(true);
 }
 
 QList<PageItem*> PageItem::itemsWeldedTo(PageItem* except)
@@ -10197,6 +10358,19 @@
 		}
 	}
 	return ret;
+}
+
+void PageItem::setWeldPoint(double DX, double DY, PageItem *pItem)
+{
+	for (int i = 0 ; i < weldList.count(); i++)
+	{
+		PageItem *pIt = weldList[i].weldItem;
+		if (pIt == pItem)
+		{
+			weldList[i].weldPoint = FPoint(DX, DY);
+			return;
+		}
+	}
 }
 
 void PageItem::unWeld()
@@ -10209,6 +10383,11 @@
 	{
 		weldingInfo wInf = weldList.at(a);
 		PageItem *pIt = wInf.weldItem;
+		if (pIt == NULL)
+		{
+			qDebug() << "unWeld - null pointer in weldList";
+			continue;
+		}
 		for (int b = 0 ; b < pIt->weldList.count(); b++)
 		{
 			weldingInfo wInf2 = pIt->weldList.at(b);
@@ -10242,3 +10421,29 @@
 	weldList.clear();
 }
 
+QString PageItem::getItemTextSaxed(int selStart, int selLength)
+{
+	if (selStart < 0 || selLength < 0)
+		return QString();
+
+	StoryText it(m_Doc);
+	it.setDefaultStyle(itemText.defaultStyle());
+
+	if (selLength == 0)
+		selLength = 1;
+	itemText.deselectAll();
+	itemText.select(selStart, selLength);
+	it.insert(0, itemText, true);
+	itemText.deselectAll();
+
+	//saxing text
+	std::ostringstream xmlString;
+	SaxXML xmlStream(xmlString);
+	xmlStream.beginDoc();
+	it.saxx(xmlStream, "SCRIBUSTEXT");
+	xmlStream.endDoc();
+	std::string xml(xmlString.str());
+	return QString(xml.c_str());
+}
+
+

Modified: trunk/Scribus/scribus/pageitem.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/pageitem.h
==============================================================================
--- trunk/Scribus/scribus/pageitem.h (original)
+++ trunk/Scribus/scribus/pageitem.h Sat Oct 27 15:56:36 2012
@@ -72,6 +72,7 @@
 class PageItem_RegularPolygon;
 class PageItem_Table;
 class PageItem_TextFrame;
+class PageItem_NoteFrame;
 class PageItem_PathText;
 class PageItem_LatexFrame;
 class PageItem_Spiral;
@@ -99,6 +100,9 @@
 	Q_PROPERTY(double lineTransparency READ lineTransparency WRITE setLineTransparency DESIGNABLE false)
 	Q_PROPERTY(bool m_Locked READ locked WRITE setLocked DESIGNABLE false)
 	Q_PROPERTY(bool m_SizeLocked READ sizeLocked WRITE setSizeLocked DESIGNABLE false)
+	//used for notes frames
+	Q_PROPERTY(bool m_SizeHLocked READ sizeHLocked WRITE setSizeHLocked DESIGNABLE false)
+	Q_PROPERTY(bool m_SizeVLocked READ sizeVLocked WRITE setSizeVLocked DESIGNABLE false)
 	Q_PROPERTY(bool m_ImageIsFlippedV READ imageFlippedV WRITE setImageFlippedV DESIGNABLE false)
 	Q_PROPERTY(bool m_ImageIsFlippedH READ imageFlippedH WRITE setImageFlippedH DESIGNABLE false)
 	Q_PROPERTY(double lineWidth READ lineWidth WRITE setLineWidth DESIGNABLE false)
@@ -195,6 +199,7 @@
 	virtual PageItem_Polygon * asPolygon() { return NULL; }
 	virtual PageItem_PolyLine * asPolyLine() { return NULL; }
 	virtual PageItem_TextFrame * asTextFrame() { return NULL; }
+	virtual PageItem_NoteFrame * asNoteFrame() { return NULL; }
 	virtual PageItem_LatexFrame * asLatexFrame() { return NULL; }
 
 	virtual PageItem_OSGFrame * asOSGFrame() { return NULL; }
@@ -219,6 +224,8 @@
 	virtual bool isArc()			const { return false; }
 	virtual bool isSpiral()			const { return false; }
 	virtual bool isTable()			const { return false; }
+	virtual bool isNoteFrame()		const { return false; }
+	virtual bool isAutoNoteFrame()	const { return false; }
 
 	/** @brief Frame Type
 	 *
@@ -237,15 +244,7 @@
 	
 public:
 	PageItem(ScribusDoc *pa, ItemType newType, double x, double y, double w, double h, double w2, QString fill, QString outline);
-	~PageItem()
-	{
-		if (tempImageFile != NULL)
-			delete tempImageFile;
-//		if (isWeld())
-//			unWeldFromMaster(true);
-//		if (isWelded())
-//			unWeldChild();
-	}
+	~PageItem();
 
 	// Get item level relative to its parent doc or group
 	int level();
@@ -322,7 +321,8 @@
 	void SetFrameRound();
 	void setPolyClip(int up, int down = 0);
 	void updatePolyClip();
-	void updateClip();
+	//added switch for not updating welded items - used by notes frames with automatic size adjusted
+	void updateClip(bool updateWelded = true);
 	void convertClip();
 	void getBoundingRect(double *x1, double *y1, double *x2, double *y2) const;
 	void getVisualBoundingRect(double *x1, double *y1, double *x2, double *y2) const;
@@ -543,6 +543,9 @@
 	PageItem* nextInChain() { return NextBox; }
 	const PageItem* prevInChain() const { return BackBox; }
 	const PageItem* nextInChain() const { return NextBox; }
+	//you can change all code for search first or last item in chain
+	PageItem* firstInChain();
+	PageItem* lastInChain();
 	PageItem *Parent;
 
 	bool testLinkCandidate(PageItem* nextFrame);
@@ -1110,8 +1113,12 @@
 	void toggleSizeLock();
 	/** @brief Is the item's size locked? */
 	bool sizeLocked() const { return m_SizeLocked; }
+	bool sizeHLocked() const { return m_SizeHLocked || m_SizeLocked; }
+	bool sizeVLocked() const { return m_SizeVLocked || m_SizeLocked; }
 	/** @brief set lock for resizing */
 	void setSizeLocked(bool isLocked);
+	void setSizeHLocked(bool isLocked) { m_SizeHLocked = isLocked; }
+	void setSizeVLocked(bool isLocked) { m_SizeVLocked = isLocked; }
 
 	/**
 	 * @brief Does text flow around this object and how
@@ -1222,8 +1229,9 @@
 	 * @author Craig Ringer
 	 *
 	 * Usually of the form 'Copy of [name]' or 'Copy of [name] (n)'
-	 */
-	QString generateUniqueCopyName(const QString originalName) const;
+	 * cezaryece: if prependCopy is false then form '[name] (n)' is generated
+	 */
+	QString generateUniqueCopyName(const QString originalName, bool prependCopy = true) const;
 	/**
 	 * @brief Is this item printed?
 	 * @sa setPrintEnabled()
@@ -1416,6 +1424,8 @@
 	void restoreCustomLineStyle(SimpleState *state, bool isUndo);
 	void restoreArrow(SimpleState *state, bool isUndo, bool isStart);
 
+	void restorePStyle(SimpleState *state, bool isUndo);
+
 	void restoreType(SimpleState *state, bool isUndo);
 	void restoreTextFlowing(SimpleState *state, bool isUndo);
 	void restoreImageScaleMode(SimpleState *state, bool isUndo);
@@ -1570,6 +1580,11 @@
 	 */
 	bool m_SizeLocked;
 
+	/**
+	 * @for notes frames - locking horizontal or vertical size
+	**/
+	bool m_SizeHLocked;
+	bool m_SizeVLocked;
 	/**
 	 * @brief Should text flow around the item
 	 * @sa PageItem::textFlowMode(), PateItem::setTextFlowMode()
@@ -1785,6 +1800,11 @@
 	void moveWelded(double DX, double DY, int weld);
 	void moveWelded(double DX, double DY, PageItem* except = NULL);
 	void rotateWelded(double dR, double oldRot);
+	//added for autowelding feature of notes frames
+	//setting welding point with given pItem to given coords
+	void setWeldPoint(double DX, double DY, PageItem *pItem);
+	//used by notes frames to get content of notes from itemText
+	QString getItemTextSaxed(int selStart, int selLength);
 };
 
 Q_DECLARE_METATYPE(PageItem*)

Modified: trunk/Scribus/scribus/pageitem_textframe.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/pageitem_textframe.cpp
==============================================================================
--- trunk/Scribus/scribus/pageitem_textframe.cpp (original)
+++ trunk/Scribus/scribus/pageitem_textframe.cpp Sat Oct 27 15:56:36 2012
@@ -35,9 +35,12 @@
 #include "canvas.h"
 #include "commonstrings.h"
 #include "hyphenator.h"
+#include "marks.h"
+#include "notesstyles.h"
 #include "pageitem.h"
 #include "pageitem_group.h"
 #include "pageitem_textframe.h"
+#include "pageitem_noteframe.h"
 #include "prefsmanager.h"
 #include "scpage.h"
 #include "scpainter.h"
@@ -54,6 +57,8 @@
 #include "util_math.h"
 
 #include "ui/guidemanager.h"
+//don`t worry - message boxes are called only if GUI is enabled
+#include "ui/scmessagebox.h"
 
 #include <cairo.h>
 
@@ -79,6 +84,7 @@
 	unicodeTextEditMode = false;
 	unicodeInputCount = 0;
 	unicodeInputString = "";
+	m_notesFramesMap.clear();
 	
 	connect(&itemText,SIGNAL(changed()), this, SLOT(slotInvalidateLayout()));
 }
@@ -282,6 +288,8 @@
 			} // for all docItems
 		} // if(OnMasterPage.isEmpty()		
 	} // if(!Embedded)
+	else
+		qDebug() << "QRegion epmty";
 	return result;
 }
 
@@ -350,7 +358,7 @@
 
 	debugFile.close();
 }
-*/
+
 static void dumpIt(const ParagraphStyle& pstyle, QString indent = QString("->"))
 {
 	QString db = QString("%6%1/%2 @ %3: %4--%5 linespa%6: %7 align%8")
@@ -368,7 +376,7 @@
 	if (pstyle.hasParent())
 		dumpIt(*dynamic_cast<const ParagraphStyle*>(pstyle.parentStyle()), more + indent);
 }
-
+*/
 static const bool legacy = true;
 
 /*
@@ -1195,8 +1203,8 @@
 	return res;
 }
 
-
-static double calculateLineSpacing (const ParagraphStyle &style, PageItem *item)
+//cezaryece: I remove static statement as this function is used also by PageItem_NoteFrame
+double calculateLineSpacing (const ParagraphStyle &style, PageItem *item)
 {
 	if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
 	{
@@ -1330,7 +1338,6 @@
 	double EndX, OFs, wide, kernVal;
 	QString chstr;
 	ScText *hl;
-	PageItem_TextFrame* nextFrame;
 	ParagraphStyle style;
 	int opticalMargins = ParagraphStyle::OM_None;
 	
@@ -1378,6 +1385,8 @@
 	//for moving next line if glyphs are higher than that
 	double lastLineY = 0;
 	
+	QMap<int, Mark*> noteMarksPosMap;  //maping notes marks and its position in text
+
 	// dump styles
 /*	
 	for (int i=0; i < itemText.nrOfParagraphs(); ++i) {
@@ -1390,7 +1399,33 @@
 */
 	
 	setShadow();
-	if ((itemText.length() != 0)) // || (NextBox != 0))
+	int itLen = itemText.length();
+	//fast validate empty frames
+	if (itLen == 0 || firstInFrame() == itLen)
+	{
+		PageItem* next = this;
+		while (next != NULL)
+		{
+			next->invalid = false;
+			next = next->nextInChain();
+		}
+		if (!isNoteFrame() && m_Doc->notesChanged() && !m_notesFramesMap.isEmpty())
+		{ //if notes are used
+			UndoManager::instance()->setUndoEnabled(false);
+			QList<PageItem_NoteFrame*> delList;
+			foreach (PageItem_NoteFrame* nF, m_notesFramesMap.keys())
+			{
+				if (nF->notesList().isEmpty() && !nF->isAutoNoteFrame())
+					delList.append(nF);
+			}
+			while (!delList.isEmpty())
+				m_Doc->delNoteFrame(delList.takeFirst(), false);
+			UndoManager::instance()->setUndoEnabled(true);
+		}
+		return;
+	}
+
+	if ((itLen != 0)) // || (NextBox != 0))
 	{
 		// determine layout area
 		m_availableRegion = calcAvailableRegion();
@@ -1423,7 +1458,7 @@
 		double autoLS = static_cast<double>(m_Doc->typographicPrefs().autoLineSpacing) / 100.0;
 
 		// find start of first line
-		if (firstInFrame() < itemText.length())
+		if (firstInFrame() < itLen)
 		{
 			hl = itemText.item(firstInFrame());
 			style = itemText.paragraphStyle(firstInFrame());
@@ -1464,27 +1499,92 @@
 		current.mustLineEnd = current.colRight;
 		current.restartX = 0;
 		int lastStat = 0, curStat = 0;
+
+		//why emit invalidating signals each time text is changed by appling styles?
+		//this speed up layouting in case of using notes marks and drop caps
+		itemText.blockSignals(true);
 		setMaxY(-1);
 		double maxYAsc = 0.0, maxYDesc = 0.0;
 
-		for (int a = firstInFrame(); a < itemText.length(); ++a)
+		for (int a = firstInFrame(); a < itLen; ++a)
 		{
 			hl = itemText.item(a);
+			bool HasObject = hl->hasObject(m_Doc);
+			bool HasMark = hl->hasMark();
+			if (HasMark)
+			{
+				//show control characters for marks
+				hl->glyph.glyph = SpecialChars::OBJECT.unicode() + ScFace::CONTROL_GLYPHS;
+
+				hl->mark->OwnPage = OwnPage;
+				//itemPtr and itemName set to this frame only if mark type is different than MARK2ItemType
+				if (!hl->mark->isType(MARK2ItemType))
+				{
+					hl->mark->setItemPtr(this);
+					hl->mark->setItemName(itemName());
+				}
+				//anchors and indexes has no visible inserts in text
+				if (hl->mark->isType(MARKAnchorType) || hl->mark->isType(MARKIndexType))
+				{
+					hl->glyph.shrink();
+					continue;
+				}
+				//store mark pointer and position in text
+				if (hl->mark->isType(MARKNoteMasterType))
+					noteMarksPosMap.insert(a, hl->mark);
+				//set note marker charstyle
+				if (hl->mark->isNoteType())
+				{
+					TextNote* note = hl->mark->getNotePtr();
+					if (note == NULL)
+						continue;
+					hl->mark->setItemPtr(this);
+					NotesStyle* nStyle = note->notesStyle();
+						Q_ASSERT(nStyle != NULL);
+					QString chsName = nStyle->marksChStyle();
+					CharStyle newStyle(itemText.charStyle(a));
+					if ((chsName != "") && (chsName != tr("No Style")))
+					{
+						CharStyle marksStyle(m_Doc->charStyle(chsName));
+						if (!newStyle.equiv(marksStyle))
+						{
+							newStyle.setParent(chsName);
+							itemText.applyCharStyle(a, 1, marksStyle);
+						}
+					}
+					else
+						itemText.eraseCharStyle(a, 1, newStyle);
+					if (hl->mark->isType(MARKNoteMasterType))
+					{
+						if (nStyle->isSuperscriptInMaster())
+							hl->setEffects(hl->effects() | ScStyle_Superscript);
+						else
+							hl->setEffects(hl->effects() & ~ScStyle_Superscript);
+					}
+					else
+					{
+						if (nStyle->isSuperscriptInNote())
+							hl->setEffects(hl->effects() | ScStyle_Superscript);
+						else
+							hl->setEffects(hl->effects() & ~ScStyle_Superscript);
+					}
+				}
+			}
+			chstr = ExpandToken(a);
+			int chstrLen = chstr.length();
+			if (chstr.isEmpty())
+				chstr = SpecialChars::ZWNBSPACE;
+
 			curStat = SpecialChars::getCJKAttr(hl->ch);
 			if (a > 0 && itemText.text(a-1) == SpecialChars::PARSEP)
 				style = itemText.paragraphStyle(a);
 			if (current.itemsInLine == 0)
 				opticalMargins = style.opticalMargins();
-			
 			CharStyle charStyle = (hl->ch != SpecialChars::PARSEP? itemText.charStyle(a) : style.charStyle());
-			chstr = ExpandToken(a);
 			double hlcsize10 = charStyle.fontSize() / 10.0;
 			double scaleV = charStyle.scaleV() / 1000.0;
 			double scaleH = charStyle.scaleH() / 1000.0;
-			offset = hlcsize10 * (charStyle.baselineOffset() / 1000.0);
-
-			if (chstr.isEmpty())
-				chstr = SpecialChars::ZWNBSPACE;
+			double offset = hlcsize10 * (charStyle.baselineOffset() / 1000.0);
 			style.setLineSpacing (calculateLineSpacing (style, this));
 			FlopBaseline = (current.startOfCol && firstLineOffset() == FLOPBaselineGrid);
 
@@ -1516,7 +1616,7 @@
 					}
 					else if (charStyle.name() != style.dcCharStyleName())
 						charStyle.setStyle(m_Doc->charStyle(style.dcCharStyleName()));
-					itemText.setCharStyle(a, chstr.length(),charStyle);
+					itemText.setCharStyle(a, chstrLen ,charStyle);
 				}
 				else if (style.dcCharStyleName() != tr("No Style") && !style.dcCharStyleName().isEmpty())
 				//hasDropCap is cleared but is set dcCharStyleName = clear drop cap char style
@@ -1608,8 +1708,15 @@
 				// FIXME : we should ensure that fonts are loaded before calls to layout()
 				// ScFace::realCharHeight()/Ascent() ensure font is loaded thanks to an indirect call to char2CMap()
 				// ScFace::ascent() can be called safely afterwards
-				double realCharHeight = font.realCharHeight(chstr[0], 1);
-				double realCharAscent = font.realCharAscent(chstr[0], 1);
+
+				//text height, width, ascent and descent should be calculated for whole text provided by hl in current position
+				//and that may be more than one char (variable text for example)
+				double realCharHeight = 0.0, realCharAscent = 0.0;
+				for (int i = 0; i < chstrLen; ++i)
+				{
+					realCharHeight = qMax(realCharHeight, font.realCharHeight(chstr[i], 1));
+					realCharAscent = qMax(realCharAscent, font.realCharAscent(chstr[i], 1));
+				}
 				double fontAscent     = font.ascent(style.charStyle().fontSize() / 10.0);
 				if (realCharHeight == 0.0)
 					realCharHeight = font.height(style.charStyle().fontSize() / 10.0);
@@ -1619,7 +1726,7 @@
 				chs  = (10 * ((DropCapDrop + fontAscent) / realCharAscent));
 				hl->setEffects(hl->effects() | ScStyle_DropCap);
 				hl->glyph.yoffset -= DropCapDrop;
-				if ((hl->ch == SpecialChars::OBJECT) && (hl->hasObject(m_Doc)))
+				if (HasObject)
 				{
 					chs = qRound((hl->getItem(m_Doc)->height() + hl->getItem(m_Doc)->lineWidth()) * 10);
 					chsd = qRound((hl->getItem(m_Doc)->height() + hl->getItem(m_Doc)->lineWidth()) * 10);
@@ -1627,7 +1734,7 @@
 			}
 			else // ! dropCapMode
 			{
-				if ((hl->ch == SpecialChars::OBJECT) && (hl->hasObject(m_Doc)))
+				if (HasObject)
 					chs = qRound((hl->getItem(m_Doc)->height() + hl->getItem(m_Doc)->lineWidth()) * 10);
 				else
 					chs = charStyle.fontSize();
@@ -1646,7 +1753,7 @@
 			hl->glyph.yadvance = 0;
 			layoutGlyphs(*hl, chstr, hl->glyph);
 			// find out width, ascent and descent of char
-			if ((hl->ch == SpecialChars::OBJECT) && (hl->hasObject(m_Doc)))
+			if (HasObject)
 			{
 				wide = hl->getItem(m_Doc)->width() + hl->getItem(m_Doc)->lineWidth();
 				hl->glyph.xadvance = wide * hl->glyph.scaleH;
@@ -1742,7 +1849,7 @@
 			if (DropCmode)
 			{
 				// drop caps are wider...
-				if ((hl->ch == SpecialChars::OBJECT) && (hl->hasObject(m_Doc)))
+				if (HasObject)
 				{
 					double itemHeight = hl->getItem(m_Doc)->height() + hl->getItem(m_Doc)->lineWidth();
 					if (itemHeight == 0)
@@ -1756,11 +1863,19 @@
 				}
 				else
 				{
-					double realCharHeight = font.realCharHeight(chstr[0], charStyle.fontSize() / 10.0);
+					double realCharHeight = 0.0;
+					wide = 0.0; realAsce = 0.0;
+					//
+					for (int i = 0; i < chstrLen; ++i)
+					{
+						realCharHeight = qMax(realCharHeight, font.realCharHeight(chstr[i], charStyle.fontSize() / 10.0));
+						realAsce = qMax(realAsce, font.realCharHeight(chstr[i], chsd / 10.0));
+						wide += font.realCharWidth(chstr[i], chsd / 10.0);
+					}
+					wide = (wide* scaleH) + (1 - scaleH);
+					realAsce = realAsce  * scaleV + offset;
 					if (realCharHeight == 0)
 						realCharHeight = font.height(style.charStyle().fontSize() / 10.0);
-					wide = (font.realCharWidth(chstr[0], chsd / 10.0) * scaleH) + (1 - scaleH); //dropcaps are to close to next glyphs if glyphs are hard scaled
-					realAsce = font.realCharHeight(chstr[0], chsd / 10.0) * scaleV + offset;
 					asce = font.ascent(hlcsize10);
 					// qDebug() QString("dropcaps pre: chsd=%1 realCharHeight = %2 chstr=%3").arg(chsd).arg(asce).arg(chstr2[0]);
 					hl->glyph.scaleH /= hl->glyph.scaleV;
@@ -1780,15 +1895,22 @@
 					wide *= wordtracking;
 				}
 				// find ascent / descent
-				if ((hl->ch == SpecialChars::OBJECT) && (hl->hasObject(m_Doc)))
+				if (HasObject)
 					desc = realDesc = 0;
 				else
 				{
+					for (int i = 0; i < chstrLen; ++i)
+					{
+						if (chstr[i] == SpecialChars::OBJECT)
+							continue;
+						realDesc = qMax(realDesc, font.realCharDescent(chstr[i], hlcsize10));
+						realAsce = font.realCharAscent(chstr[i], hlcsize10);
+					}
+					realDesc =  realDesc * scaleV - offset;
 					desc = -font.descent(hlcsize10);
-					realDesc = font.realCharDescent(chstr[0], hlcsize10) * scaleV - offset;
 					current.rememberShrinkStretch(hl->ch, wide, style);
 				}
-				if ((hl->ch == SpecialChars::OBJECT) && (hl->hasObject(m_Doc)))
+				if (HasObject)
 				{
 					asce = hl->getItem(m_Doc)->height() + hl->getItem(m_Doc)->lineWidth();
 					realAsce = asce * scaleV + offset;
@@ -1796,7 +1918,13 @@
 				else
 				{
 					asce = font.ascent(hlcsize10);
-					realAsce = font.realCharAscent(chstr[0], hlcsize10) * scaleV + offset;
+					if (HasMark)
+						realAsce = asce * scaleV + offset;
+					else
+					{
+						for (int i = 0; i < chstrLen; ++i)
+							realAsce = qMax(realAsce, font.realCharAscent(chstr[i], hlcsize10) * scaleV + offset);
+					}
 				}
 			}
 
@@ -1809,6 +1937,9 @@
 					if (current.startOfCol)
 					{
 						lastLineY = qMax(lastLineY, extra.Top + lineCorr);
+						//fix for proper rendering first empty line (only with PARSEP)
+						if (chstr[0] == SpecialChars::PARSEP)
+							current.yPos += style.lineSpacing();
 						if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing || FlopBaseline)
 						{
 							if (current.yPos <= lastLineY)
@@ -2021,14 +2152,14 @@
 					diff = realAsce - (current.yPos - lastLineY);
 				else if (style.lineSpacingMode() != ParagraphStyle::FixedLineSpacing)
 				{
-					if ((hl->ch == SpecialChars::OBJECT) && (hl->hasObject(m_Doc)))
+					if (HasObject)
 						diff = (hl->getItem(m_Doc)->height() + hl->getItem(m_Doc)->lineWidth()) * scaleV + offset - (current.yPos - lastLineY);
 					else
 						diff = font.realCharAscent(QChar('l'), hlcsize10) * scaleV + offset - (current.yPos - lastLineY);
 				}
 				else
 				{
-					if ((hl->ch == SpecialChars::OBJECT) && (hl->hasObject(m_Doc)))
+					if (HasObject)
 						diff = (hl->getItem(m_Doc)->height() + hl->getItem(m_Doc)->lineWidth()) * scaleV + offset - (current.yPos - lastLineY);
 				}
 				if (diff >= 1 || (!DropCmode && diff > 0))
@@ -2141,8 +2272,12 @@
 			
 			// remember y pos
 			if (DropCmode)
-				hl->glyph.yoffset -= font.realCharHeight(chstr[0], chsd / 10.0) - font.realCharAscent(chstr[0], chsd / 10.0);
-
+			{
+				double yoffset = 0.0;
+				for (int i = 0; i < chstrLen; ++i)
+					yoffset = qMax(yoffset, font.realCharHeight(chstr[i], chsd / 10.0) - font.realCharAscent(chstr[i], chsd / 10.0));
+				hl->glyph.yoffset -= yoffset;
+			}
 			// remember x pos
 			double breakPos = current.xPos;
 			
@@ -2662,6 +2797,7 @@
 							maxDX = 0;
 						}
 					}
+					lastLineY = current.rowDesc;
 					current.mustLineEnd = current.colRight;
 					current.restartRowIndex = current.restartIndex;
 				}
@@ -2811,20 +2947,31 @@
 
 			if (moveLinesFromPreviousFrame ()) {
 				layout ();  // line moving ensures that this won't be an endless loop
+				itemText.blockSignals(false);
 				return;
 			}
 		}
 	}
 	MaxChars = itemText.length();
 	invalid = false;
-
-	nextFrame = dynamic_cast<PageItem_TextFrame*>(NextBox);
-	while (nextFrame != NULL)
-	{
+	if (!isNoteFrame() && (!m_Doc->notesList().isEmpty() || m_Doc->notesChanged()))
+	{ //if notes are used
+		UndoManager::instance()->setUndoEnabled(false);
+		NotesInFrameMap notesMap = updateNotesFrames(noteMarksPosMap);
+		if (notesMap != m_notesFramesMap)
+		{
+			updateNotesMarks(notesMap);
+			notesFramesLayout();
+		}
+		UndoManager::instance()->setUndoEnabled(true);
+	}
+	if (NextBox != NULL) 
+	{
+		PageItem_TextFrame * nextFrame = dynamic_cast<PageItem_TextFrame*>(NextBox);
 		nextFrame->invalid   = true;
 		nextFrame->firstChar = MaxChars;
-		nextFrame = dynamic_cast<PageItem_TextFrame*>(nextFrame->NextBox);
-	}
+	}
+	itemText.blockSignals(false);
 //	qDebug("textframe: len=%d, done relayout", itemText.length());
 	return;
 			
@@ -2832,6 +2979,18 @@
 	invalid = false;
 
 	adjustParagraphEndings ();
+
+	if (!isNoteFrame() && (!m_Doc->notesList().isEmpty() || m_Doc->notesChanged()))
+	{
+		UndoManager::instance()->setUndoEnabled(false);
+		NotesInFrameMap notesMap = updateNotesFrames(noteMarksPosMap);
+		if (notesMap != m_notesFramesMap)
+		{
+			updateNotesMarks(notesMap);
+			notesFramesLayout();
+		}
+		UndoManager::instance()->setUndoEnabled(true);
+	}
 
 	PageItem_TextFrame * next = dynamic_cast<PageItem_TextFrame*>(NextBox);
 	if (next != NULL)
@@ -2857,12 +3016,13 @@
 		next->layout();
 	}
 //	qDebug("textframe: len=%d, done relayout (no room %d)", itemText.length(), MaxChars);
-}
-
-void PageItem_TextFrame::invalidateLayout()
+	itemText.blockSignals(false);
+}
+
+void PageItem_TextFrame::invalidateLayout(bool wholeChain)
 {
-	const bool wholeChain = true;
-	this->invalid = true;
+	//const bool wholeChain = true;
+	invalid = true;
 	if (wholeChain)
 	{
 		PageItem *prevFrame = this->prevInChain();
@@ -2878,12 +3038,39 @@
 			nextFrame = nextFrame->nextInChain();
 		}
 	}
+}
+
+void PageItem_TextFrame::slotInvalidateLayout()
+{
+	invalidateLayout(true);
+}
+
+bool PageItem_TextFrame::isValidChainFromBegin()
+{
+	if (invalid)
+		return false;
+	if (BackBox == NULL)
+		return !invalid;
+
+	PageItem* prev = prevInChain();
+	while (prev != NULL)
+	{
+		if (prev->invalid)
+			return false;
+		prev = prev->prevInChain();
+	}
+	return true;
 }
 
 void PageItem_TextFrame::DrawObj_Item(ScPainter *p, QRectF cullingArea)
 {
 	if(invalid)
+	{
+		if (isNoteFrame() && asNoteFrame()->deleteIt)
+		//do not layout notes frames which should be deleted
+			return;
 		layout();
+	}
 	if (invalid)
 		return;
 	QTransform pf2;
@@ -3259,15 +3446,19 @@
 			bool previousWasObject(false);
 			double selX = ls.x;
 			ScText *hls = 0;
-			for (int as = ls.firstItem; as <= qMin(ls.lastItem, itemText.length() - 1); ++as)
+			int last = qMin(ls.lastItem, itemText.length() - 1);
+			for (int as = ls.firstItem; as <= last; ++as)
 			{
 				bool selecteds = itemText.selected(as);
 				hls = itemText.item(as);
+				bool HasObject = hls->hasObject(m_Doc);
+				if (hls->mark != NULL && (hls->mark->isType(MARKAnchorType) || hls->mark->isType(MARKIndexType)))
+					continue;
 				if(selecteds)
 				{
 					const CharStyle& charStyleS(itemText.charStyle(as));
 					if(((as > ls.firstItem) && (charStyleS != itemText.charStyle(as-1)))
-						|| ((!selectedFrame.isNull()) && (hls->ch == SpecialChars::OBJECT))
+						|| ((!selectedFrame.isNull()) && HasObject)
 					    || previousWasObject)
 					{
 						sFList << selectedFrame;
@@ -3296,7 +3487,7 @@
 							asce = font.ascent(fontSize);
 							wide = hls->glyph.wide();
 							QRectF scr;
-							if ((hls->ch == SpecialChars::OBJECT)  && (hls->hasObject(m_Doc)))
+							if (HasObject)
 							{
 								double ww = (hls->getItem(m_Doc)->width() + hls->getItem(m_Doc)->lineWidth()) * hls->glyph.scaleH;
 								double hh = (hls->getItem(m_Doc)->height() + hls->getItem(m_Doc)->lineWidth()) * hls->glyph.scaleV;
@@ -3332,7 +3523,7 @@
 
 			QColor tmp;
 			ScText *hl = 0;
-			for (int a = ls.firstItem; a <= qMin(ls.lastItem, itemText.length() - 1); ++a)
+			for (int a = ls.firstItem; a <= last; ++a)
 			{
 				hl = itemText.item(a);
 				const CharStyle& charStyle(itemText.charStyle(a));
@@ -3389,10 +3580,19 @@
 					{
 						p->save();//SA4
 						p->translate(CurX, ls.y);
-						if ((hl->ch == SpecialChars::OBJECT) && (hl->hasObject(m_Doc)))
+						if (hl->hasObject(m_Doc))
 							DrawObj_Embedded(p, cullingArea, charStyle, hl->getItem(m_Doc));
 						else
+						{
+							//control chars for marks
+							if (m_Doc->guidesPrefs().showControls && hl->hasMark() && (hl->glyph.glyph != SpecialChars::OBJECT))
+							{
+								GlyphLayout markGlyph;
+								layoutGlyphs(charStyle,SpecialChars::OBJECT, markGlyph);
+								drawGlyphs(p, charStyle, markGlyph);
+							}
 							drawGlyphs(p, charStyle, hl->glyph);
+						}
 						p->restore();//RE4
 					}
 					// Unneeded now that glyph xadvance is set appropriately for inline objects by layout() - JG
@@ -3586,7 +3786,7 @@
 		//Draw the overflow icon
 		if (frameOverflows())
 		{
-			if (!(m_Doc->drawAsPreview))
+			if (!m_Doc->drawAsPreview)
 				drawOverflowMarker(p);
 		}
 		if ((m_Doc->guidesPrefs().colBordersShown) && (!m_Doc->drawAsPreview))
@@ -3630,9 +3830,12 @@
 	ParagraphStyle defaultStyle = nextItem->itemText.defaultStyle();
 	nextItem->itemText.selectAll();
 	nextItem->asTextFrame()->deleteSelectedTextFromFrame();
+	if (!isNoteFrame())
+	{
 	if(UndoManager::undoEnabled())
 		undoManager->getLastUndo()->setName(Um::ClearText);
 	nextItem->itemText.setDefaultStyle(defaultStyle);
+	}
 
 	while (nextItem != 0)
 	{
@@ -3785,8 +3988,13 @@
 				}
 //				Tinput = true;
 				m_Doc->scMW()->setTBvals(this);
+				if (isAutoNoteFrame() && m_Doc->notesChanged())
+				{
+					Q_ASSERT(asNoteFrame()->masterFrame());
+					asNoteFrame()->masterFrame()->invalid = true;
+				}
+				else
 				update();
-				doc()->changed();
 				keyRepeat = false;
 				return;
 			}
@@ -4075,6 +4283,15 @@
 			{
 				deleteSelectedTextFromFrame();
 				m_Doc->scMW()->setTBvals(this);
+				if (isAutoNoteFrame() && asNoteFrame()->notesList().isEmpty())
+				{
+					if (!asNoteFrame()->isEndNotesFrame())
+					{
+						Q_ASSERT(asNoteFrame()->masterFrame());
+						asNoteFrame()->masterFrame()->invalid = true;
+					}
+				}
+				else
 				update();
 //				view->RefreshItem(this);
 			}
@@ -4090,10 +4307,20 @@
 		if (itemText.lengthOfSelection() == 0)
 			itemText.select(itemText.cursorPosition(), 1, true);
 		deleteSelectedTextFromFrame();
-		updateLayout();
+		if (isAutoNoteFrame() && asNoteFrame()->notesList().isEmpty())
+		{
+			if (!asNoteFrame()->isEndNotesFrame())
+			{
+				Q_ASSERT(asNoteFrame()->masterFrame());
+				asNoteFrame()->masterFrame()->invalid = true;
+			}
+		}
+		else
+		{
+			layout();
 		if (oldLast != lastInFrame() && NextBox != 0 && NextBox->invalid)
 			NextBox->updateLayout();
-		update();
+		}
 //		Tinput = false;
 //		if ((cr == QChar(13)) && (itemText.length() != 0))
 //		{
@@ -4101,7 +4328,6 @@
 //			Tinput = false;
 //		}
 		m_Doc->scMW()->setTBvals(this);
-		doc()->changed();
 //		view->RefreshItem(this);
 		break;
 	case Qt::Key_Backspace:
@@ -4111,6 +4337,15 @@
 			{
 				deleteSelectedTextFromFrame();
 				m_Doc->scMW()->setTBvals(this);
+				if (isAutoNoteFrame() && asNoteFrame()->notesList().isEmpty())
+				{
+					if (!asNoteFrame()->isEndNotesFrame())
+					{
+						Q_ASSERT(asNoteFrame()->masterFrame());
+						asNoteFrame()->masterFrame()->invalid = true;
+					}
+				}
+				else
 				update();
 			}
 			break;
@@ -4125,14 +4360,25 @@
 		}
 		deleteSelectedTextFromFrame();
 //		Tinput = false;
-		if ((cr == QChar(13)) && (itemText.length() != 0))
-		{
+//		if ((cr == QChar(13)) && (itemText.length() != 0))
+//		{
 //			m_Doc->chAbStyle(this, findParagraphStyle(m_Doc, itemText.paragraphStyle(qMax(CPos-1,0))));
 //			Tinput = false;
-		}
-		updateLayout();
+//		}
+		if (isAutoNoteFrame() && asNoteFrame()->notesList().isEmpty())
+		{
+			if (!asNoteFrame()->isEndNotesFrame())
+			{
+				Q_ASSERT(asNoteFrame()->masterFrame());
+				asNoteFrame()->masterFrame()->invalid = true;
+			}
+		}
+		else
+		{
+			layout();
 		if (oldLast != lastInFrame() && NextBox != 0 && NextBox->invalid)
 			NextBox->updateLayout();
+		}
 		if (itemText.cursorPosition() < firstInFrame())
 		{
 			itemText.setCursorPosition( firstInFrame() );
@@ -4147,11 +4393,12 @@
 			}
 		}
 		m_Doc->scMW()->setTBvals(this);
-		update();
-		doc()->changed();
+//		update();
 //		view->RefreshItem(this);
 		break;
 	default:
+		if (isNoteFrame() && itemText.cursorPosition() == 0)
+			break; //avoid inserting chars before first note mark
 		bool doUpdate = false;
 		UndoTransaction* activeTransaction = NULL;
 		if (itemText.lengthOfSelection() > 0) //(kk < 0x1000)
@@ -4199,7 +4446,13 @@
 					ss->set("ETEA", QString("insert_frametext"));
 					ss->set("TEXT_STR", QString(SpecialChars::TAB));
 					ss->set("START", itemText.cursorPosition());
-					undoManager->action(this, ss);
+					UndoObject * undoTarget = this;
+					if (isNoteFrame())
+					{
+						undoTarget = m_Doc;
+						ss->set("noteframeName", getUName());
+					}
+					undoManager->action(undoTarget, ss);
 				}
 			}
 			itemText.insertChars(QString(SpecialChars::TAB), true);
@@ -4220,7 +4473,12 @@
 					ss->set("ETEA", QString("insert_frametext"));
 					ss->set("TEXT_STR",uc);
 					ss->set("START", itemText.cursorPosition());
-					undoManager->action(this, ss);
+					UndoObject * undoTarget = this;
+					if (isNoteFrame())
+					{						undoTarget = m_Doc;
+						ss->set("noteframeName", getUName());
+					}
+					undoManager->action(undoTarget, ss);
 				}
 			}
 			itemText.insertChars(uc, true);
@@ -4258,12 +4516,21 @@
 			}
 			// update layout immediately, we need MaxChars to be correct to detect 
 			// if we need to move to next frame or not
-			updateLayout();
+			if (isAutoNoteFrame() && asNoteFrame()->notesList().isEmpty())
+			{
+				if (!asNoteFrame()->isEndNotesFrame())
+				{
+					Q_ASSERT(asNoteFrame()->masterFrame());
+					asNoteFrame()->masterFrame()->invalid = true;
+				}
+			}
+			else
+				update();
 			if (oldLast != lastInFrame() && NextBox != 0 && NextBox->invalid)
 				NextBox->updateLayout();
-			doc()->changed();
 		}
 		//check if cursor need to jump to next linked frame
+		//but not for notes frames can`t be updated as may disapper during update
 		if ((itemText.cursorPosition() > lastInFrame() + 1) && (lastInFrame() < (itemText.length() - 2)) && NextBox != 0)
 		{
 			view->Deselect(true);
@@ -4278,12 +4545,17 @@
 		keyRepeat = false;
 }
 
-void PageItem_TextFrame::deleteSelectedTextFromFrame()
+void PageItem_TextFrame::deleteSelectedTextFromFrame(/*bool findNotes*/)
 {
-	if (itemText.lengthOfSelection() > 0) {
-		if(UndoManager::undoEnabled()){
+	if (itemText.lengthOfSelection() == 0)
+	{
+		itemText.select(itemText.cursorPosition(),1);
+		HasSel = true;
+	}
 			int start = itemText.startOfSelection();
 			int stop = itemText.endOfSelection();
+	int marksNum = 0;
+	if(UndoManager::undoEnabled()) {
 			int lastPos = start;
 			CharStyle lastParent = itemText.charStyle(start);
 			UndoState* state = undoManager->getLastUndo();
@@ -4296,13 +4568,38 @@
 				is = dynamic_cast<ScItemState<CharStyle>*>(ts->at(ts->sizet()-1));
 				state = ts->at(0);
 			}
-			UndoTransaction trans = undoManager->beginTransaction(Um::Selection,Um::IDelete,Um::Delete,"",Um::IDelete);
+		UndoTransaction* trans = new UndoTransaction(undoManager->beginTransaction(Um::Selection,Um::IDelete,Um::Delete,"",Um::IDelete));
+
+		//find and delete notes and marks in selected text
+		QList<QPair<TextNote*, int> > notes2DEL;
+		if (isNoteFrame()/* && findNotes*/)
+		{
+			//find and delete notes
+			//if marks are in notes then they will be deleted further while note is physicaly deleted
+			for (int i=start; i < stop; ++i)
+			{
+				if (i == itemText.length())
+					break;
+				ScText* hl = itemText.item(i);
+				if (hl->hasMark() && hl->mark->isType(MARKNoteFrameType))
+					notes2DEL.append(QPair<TextNote*, int>(hl->mark->getNotePtr(), i));
+			}
+		}
+		else
+		{
+			//delete marks from selected text (with undo)
+			marksNum = removeMarksFromText(true);
+			stop -= marksNum;
+		}
+		//delete text
 			for (int i=start; i <= stop; ++i)
 			{
-				const CharStyle& curParent(itemText.charStyle(i));
-				if (curParent.equiv(lastParent) && i != stop)
-					continue;
-
+			ScText* hl = NULL;
+			if (i < itemText.length())
+				hl = itemText.item(i);
+			const CharStyle& curParent = itemText.charStyle(i);
+			if (i==stop || !curParent.equiv(lastParent) || (hl!=NULL && hl->hasMark() && hl->mark->isType(MARKNoteFrameType)))
+			{
 				added = false;
 				lastIsDelete = false;
 				if (is && ts && dynamic_cast<ScItemState<CharStyle>*>(ts->at(0))->get("ETEA") == "delete_frametext" && lastPos<is->getInt("START"))
@@ -4325,28 +4622,84 @@
 				}
 				if (!added)
 				{
+					UndoObject * undoTarget = this;
+					is = NULL;
+					if (i - lastPos > 0)
+					{
 					is = new ScItemState<CharStyle>(Um::DeleteText,"",Um::IDelete);
 					is->set("DELETE_FRAMETEXT", "delete_frametext");
 					is->set("ETEA", QString("delete_frametext"));
 					is->set("TEXT_STR",itemText.text(lastPos,i - lastPos));
 					is->set("START", start);
 					is->setItem(lastParent);
+					}
+					//delete selected notes from notes frame
+					if (isNoteFrame())
+					{
+						undoTarget = m_Doc; //undo target is doc for notes as after deleting last note notesframe can be deleted
+						if (is)
+							is->set("noteframeName", getUName());
+						//remove marks from notes
+						for (int ii = notes2DEL.count() -1; ii >= 0; --ii)
+						{
+							TextNote* note = notes2DEL.at(ii).first;
+							Q_ASSERT(note != NULL);
+							if (note->textLen > 0)
+							{
+								itemText.deselectAll();
+								itemText.select(notes2DEL.at(ii).second + 1, note->textLen);
+								removeMarksFromText(true);
+							}
+						}
+						asNoteFrame()->updateNotesText();
+						for (int ii = notes2DEL.count() -1; ii >= 0; --ii)
+						{
+							TextNote* note = notes2DEL.at(ii).first;
+							Q_ASSERT(note != NULL);
+							m_Doc->setUndoDelNote(note);
+							if (note->isEndNote())
+								m_Doc->flag_updateEndNotes = true;
+							m_Doc->deleteNote(note);
+						}
+						if(is)
+						{
+							if (!ts || !lastIsDelete){
+								undoManager->action(undoTarget, is);
+								ts = NULL;
+							}
+							else
+								ts->pushBack(undoTarget,is);
+						}
+						break;
+					}
+					if (is)
+					{
 					if(!ts || !lastIsDelete){
-						undoManager->action(this, is);
+							undoManager->action(undoTarget, is);
 						ts = NULL;
 					}
 					else
-						ts->pushBack(this,is);
+							ts->pushBack(undoTarget,is);
+					}
 				}
 				lastPos = i;
 				lastParent = curParent;
 			}
-			trans.commit();
-		}
-		itemText.setCursorPosition( itemText.startOfSelection() );
+		}
+		if (trans)
+		{
+			trans->commit();
+			delete trans;
+			trans = NULL;
+		}
+	}
+	else //remove marks without undo
+		marksNum =removeMarksFromText(false);
+	itemText.setCursorPosition( start );
+	//for sure text is still selected
+	itemText.select(start, stop - start - marksNum);
 		itemText.removeSelection();
 		HasSel = false;
-	}
 //	m_Doc->updateFrameItems();
 	m_Doc->scMW()->DisableTxEdit();
 }
@@ -4644,8 +4997,39 @@
 	return true;
 }
 
+void PageItem_TextFrame::togleEditModeActions()
+{
+	bool editMode = (m_Doc->appMode == modeEdit);
+	bool masterMode = m_Doc->masterPageMode();
+	m_Doc->scMW()->scrActions["insertMarkVariableText"]->setEnabled(editMode);
+	m_Doc->scMW()->scrActions["insertMarkAnchor"]->setEnabled(editMode && !masterMode);
+	m_Doc->scMW()->scrActions["insertMarkItem"]->setEnabled(editMode && !masterMode);
+	m_Doc->scMW()->scrActions["insertMark2Mark"]->setEnabled(editMode && !masterMode);
+	m_Doc->scMW()->scrActions["insertMarkNote"]->setEnabled(editMode && !masterMode && !isNoteFrame());
+	//	scrActions["insertMarkIndex"]->setEnabled(editMode && !masterMode);
+	bool enableEditMark = false;
+	if (editMode && (itemText.cursorPosition() < itemText.length()))
+	{
+		ScText *hl = itemText.item(itemText.cursorPosition());
+		if (hl->hasMark())
+		{
+			Mark* mrk = hl->mark;
+			//notes marks in note frames are not editable
+			if (!mrk->isType(MARKNoteFrameType))
+				enableEditMark = true;
+		}
+	}
+	m_Doc->scMW()->scrActions["editMark"]->setEnabled(enableEditMark);
+}
+
 void PageItem_TextFrame::applicableActions(QStringList & actionList)
 {
+	actionList << "insertMarkVariableText";
+	if (!m_Doc->masterPageMode())
+		actionList << "insertMarkAnchor";
+	//notes frames are not simply text frames
+	if (isNoteFrame())
+		return;
 	actionList << "fileImportText";
 	actionList << "fileImportAppendText";
 	actionList << "toolsEditWithStoryEditor";
@@ -4678,9 +5062,422 @@
 	return QString();
 }
 
-void PageItem_TextFrame::slotInvalidateLayout()
+bool PageItem_TextFrame::hasMark(NotesStyle *NS)
 {
-	invalidateLayout();
+	if (isNoteFrame())
+		return (asNoteFrame()->notesStyle() == NS);
+
+	if (NS == NULL)
+	{
+		//find any mark
+		if (!m_notesFramesMap.isEmpty())
+			return true;
+		for (int i=firstInFrame(); i <= lastInFrame(); ++i)
+			if (itemText.item(i)->hasMark())
+				return true;
+	}
+	else
+	{
+		for (int pos = firstInFrame(); pos <= lastInFrame(); ++pos)
+		{
+			ScText* hl = itemText.item(pos);
+			if (hl->hasMark())
+			{
+				TextNote* note = hl->mark->getNotePtr();
+				if (note != NULL && (note->notesStyle() == NS))
+					return true;
+			}
+		}
+	}
+	return false;
+}
+
+bool PageItem_TextFrame::hasNoteFrame(NotesStyle *NS, bool inChain)
+{
+	if (isNoteFrame())
+		return false;
+	if (m_notesFramesMap.isEmpty())
+		return false;
+	if (NS == NULL)
+	{ //check if any notes are in frame or whole chain
+		if (!inChain)
+			return !m_notesFramesMap.isEmpty();
+		else
+		{
+			PageItem* item = this;
+			item = firstInChain();
+			while (item != NULL)
+			{
+				if (item->asTextFrame()->hasNoteFrame(NULL, false))
+					return true;
+				item = item->nextInChain();
+			}
+			return false;
+		}
+	}
+	PageItem* item = this;
+	if (inChain)
+		item = firstInChain();
+	while (item != NULL)
+	{
+		QMap<PageItem_NoteFrame*, QList<TextNote*> >::iterator it = m_notesFramesMap.begin();
+		QMap<PageItem_NoteFrame*, QList<TextNote*> >::iterator end = m_notesFramesMap.end();
+		while (it != end)
+		{
+			if (it.key()->notesStyle() == NS)
+				return true;
+			++it;
+		}
+		if (!inChain)
+			break;
+		item = item->nextInChain();
+	}
+	return false;
+}
+
+void PageItem_TextFrame::delAllNoteFrames(bool doUpdate)
+{
+	int oldItemsCount = m_Doc->Items->count();
+
+	QList<PageItem_NoteFrame*> delList;
+	foreach (PageItem_NoteFrame* nF, m_notesFramesMap.keys())
+	{
+		if (nF->notesList().isEmpty() && !nF->isAutoNoteFrame())
+			delList.append(nF);
+	}
+	while (!delList.isEmpty())
+	{
+		PageItem_NoteFrame* nF = delList.takeFirst();
+		m_Doc->delNoteFrame(nF);
+	}
+
+	//check if doc need update
+	if (doUpdate && (oldItemsCount != m_Doc->Items->count()))
+	{
+		m_Doc->changed();
+		m_Doc->regionsChanged()->update(QRectF());
+	}
+	m_Doc->setNotesChanged(true);
+}
+
+Mark* PageItem_TextFrame::selectedMark(bool onlySelection)
+{ //return pointer to first mark in selected (or whole) text
+	
+	bool omitNotes = true; //do not return notes marks (for searching notes use selectedNotesMark()
+	int start = 0;
+	int stop = 0;
+	if (onlySelection)
+	{
+		if (itemText.lengthOfSelection() > 0)
+		{
+			//only selection
+			start = itemText.startOfSelection();
+			stop = start + itemText.lengthOfSelection();
+		}
+		else //in edit mode only one char in cursor position
+		{
+			if (m_Doc->appMode == modeEdit)
+			{
+				//only char after cursor
+				start = itemText.cursorPosition();
+				stop = start + 1;
+				if (stop > itemText.length())
+					return NULL;
+			}
+			else
+			{
+				//only frame
+				start = firstInFrame();
+				stop = lastInFrame();
+				if (start == stop)
+					return NULL;
+			}
+		}
+		
+	}
+	else //in whole text
+		stop = itemText.length();
+	
+	for (int pos = start; pos < stop; ++pos)
+	{
+		ScText* hl = itemText.item(pos);
+		if (hl->hasMark())
+		{
+			if (omitNotes && (hl->mark->isType(MARKNoteMasterType) || hl->mark->isType(MARKNoteFrameType)))
+				continue;
+			return hl->mark;
+		}
+	}
+	return NULL;
+}
+
+TextNote* PageItem_TextFrame::selectedNoteMark(ScText* &hl, bool onlySelection)
+{
+	//return pointer to note from first mark found in text
+	int start = 0;
+	int stop = itemText.length();
+	if (onlySelection)
+	{
+		if (itemText.lengthOfSelection() > 0)
+		{
+			start = itemText.startOfSelection();
+			stop = start + itemText.lengthOfSelection();
+		}
+		else
+			return NULL;
+	}
+	MarkType typ = isNoteFrame()? MARKNoteFrameType : MARKNoteMasterType;
+	for (int pos = start; pos < stop; ++pos)
+	{
+		ScText* hl = itemText.item(pos);
+		if (hl->hasMark() && hl->mark->isType(typ))
+			return hl->mark->getNotePtr();
+	}
+	return NULL;
+}
+
+TextNote* PageItem_TextFrame::selectedNoteMark(bool onlySelection)
+{
+	ScText* hl = NULL;
+	return selectedNoteMark(hl, onlySelection);
+}
+
+NotesInFrameMap PageItem_TextFrame::updateNotesFrames(QMap<int, Mark*> noteMarksPosMap)
+{
+	NotesInFrameMap notesMap; //= m_notesFramesMap;
+	QMap<int, Mark*>::Iterator it = noteMarksPosMap.begin();
+	QMap<int, Mark*>::Iterator end = noteMarksPosMap.end();
+	PageItem* lastItem = this;
+	while (it != end)
+	{
+		if (it.key() <= lastInFrame())
+		{
+			Mark* mark = it.value();
+			mark->setItemPtr(this);
+			mark->setItemName(itemName());
+
+			TextNote* note = mark->getNotePtr();
+			Q_ASSERT(note != NULL);
+			if (note == NULL)
+			{
+				qWarning() << "note mark without valid note pointer";
+				note = m_Doc->newNote(m_Doc->m_docNotesStylesList.at(0));
+				note->setMasterMark(mark);
+				mark->setNotePtr(note);
+			}
+			NotesStyle* NS = note->notesStyle();
+			PageItem_NoteFrame* nF = NULL;
+			if (NS->isEndNotes())
+				nF = m_Doc->endNoteFrame(NS, this);
+			else
+				nF = itemNoteFrame(NS);
+			if (nF == NULL)
+			{
+				//creating new noteframe
+				if (NS->isEndNotes())
+				{
+					//create new endnotes frame
+					double x,y,w,h;
+					const ScPage* scP = m_Doc->page4EndNotes(NS, this);
+					x = scP->Margins.Left + m_Doc->rulerXoffset + scP->xOffset();
+					y = scP->Margins.Top + m_Doc->rulerYoffset + scP->yOffset();
+					w = scP->width() - scP->Margins.Left - scP->Margins.Right;
+					h = calculateLineSpacing(itemText.defaultStyle(), this);
+					nF = m_Doc->createNoteFrame(note->notesStyle(), x, y, w, h, m_Doc->itemToolPrefs().shapeLineWidth, CommonStrings::None, m_Doc->itemToolPrefs().textFont);
+					switch (NS->range())
+					{ //insert pointer to endnoteframe into m_Doc->m_endNotesFramesMap
+						case NSRdocument:
+							m_Doc->setEndNoteFrame(nF, (void*) NULL);
+							break;
+						case NSRsection:
+							m_Doc->setEndNoteFrame(nF, m_Doc->getSectionKeyForPageIndex(OwnPage));
+						case NSRstory:
+							m_Doc->setEndNoteFrame(nF, (void*) firstInChain());
+							break;
+						case NSRpage:
+							m_Doc->setEndNoteFrame(nF, (void*) m_Doc->DocPages.at(OwnPage));
+							break;
+						case NSRframe:
+							qDebug() << "Frame range is prohibited for end-notes";
+							Q_ASSERT(false);
+							break;
+					}
+				}
+				else
+					//create new footnotes frame for that text frame
+					nF = m_Doc->createNoteFrame(this, note->notesStyle(), m_Doc->DocItems.indexOf(lastItem));
+				//insert in map noteframe with empty list of notes
+				m_notesFramesMap.insert(nF, QList<TextNote*>());
+				m_Doc->setNotesChanged(true);
+			}
+			else if (NS->isEndNotes())
+			{//check endnotes frame proper page
+				const ScPage* scP = m_Doc->page4EndNotes(NS, this);
+				if (scP->pageNr() != nF->OwnPage)
+				{
+					double x,y;
+					x = scP->Margins.Left + m_Doc->rulerXoffset + scP->xOffset();
+					y = scP->Margins.Top + m_Doc->rulerYoffset + scP->yOffset();
+					if ((scP->pageNr() != nF->OwnPage) || (nF->xPos() > (x + scP->width())) || nF->yPos() > (y + scP->height()))
+					{
+						undoManager->setUndoEnabled(false);
+						nF->setXYPos(x,y);
+						undoManager->setUndoEnabled(true);
+					}
+				}
+			}
+			QList<TextNote*> nList;//list of notes in current noteFrame
+			nList = notesMap.value(nF);
+			if (!nList.contains(note))
+			{
+				nList.append(note);
+				notesMap.insert(nF, nList);
+			}
+			if (!nF->isEndNotesFrame())
+				lastItem = nF;
+		}
+		else
+			break;
+		++it;
+	}
+	return notesMap;
+}
+
+void PageItem_TextFrame::updateNotesMarks(NotesInFrameMap notesMap)
+{
+	bool docWasChanged = false;
+
+//	QList<PageItem_NoteFrame*> curr_footNotesList;
+//	QList<PageItem_NoteFrame*> old_footNotesList;
+//	QList<PageItem_NoteFrame*> curr_endNotesList;
+//	QList<PageItem_NoteFrame*> old_endNotesList;
+
+	
+//	foreach(PageItem_NoteFrame* nF, notesMap.keys())
+//	{
+//		if (nF->isEndNotesFrame())
+//			curr_endNotesList.append(nF);
+//		else if (!notesMap.value(nF).isEmpty())
+//			curr_footNotesList.append(nF);
+//	}
+//	foreach(PageItem_NoteFrame* nF, m_notesFramesMap.keys())
+//	{
+//		if (nF->isEndNotesFrame())
+//			old_endNotesList.append(nF);
+//		else
+//			old_footNotesList.append(nF);
+//	}
+//	//check for endnotes marks change in current frame
+//	foreach (PageItem_NoteFrame* nF, old_endNotesList)
+//	{
+//		if (nF->deleteIt)
+//		{
+//			m_Doc->delNoteFrame(nF,true);
+//			docWasChanged = true;
+//		}
+//		else if (!notesMap.contains(nF) || (m_notesFramesMap.value(nF) != notesMap.value(nF)))
+//		{
+//			m_Doc->endNoteFrameChanged(nF);
+//			docWasChanged = true;
+//		}
+//	}
+	//check if some notes frames are not used anymore
+	foreach (PageItem_NoteFrame* nF, m_notesFramesMap.keys())
+	{
+		if (nF->deleteIt || (nF->isAutoNoteFrame() && !notesMap.keys().contains(nF)))
+		{
+			m_Doc->delNoteFrame(nF,true);
+			docWasChanged = true;
+		}
+		else
+		{
+			QList<TextNote*> nList = notesMap.value(nF);
+			if (nList != nF->notesList() || m_Doc->notesChanged())
+			{
+				nF->updateNotes(nList, (!nF->isEndNotesFrame() && !nF->notesList().isEmpty()));
+				docWasChanged = true;
+			}
+		}
+	}
+	if (m_notesFramesMap != notesMap)
+	{
+		docWasChanged = true;
+		foreach (PageItem_NoteFrame* nF, m_notesFramesMap.keys())
+		{
+			if (notesMap.contains(nF))
+			{
+				m_notesFramesMap.insert(nF, notesMap.value(nF));
+				notesMap.remove(nF);
+			}
+			else if (nF->isAutoNoteFrame() || nF->isEndNotesFrame())
+				m_notesFramesMap.remove(nF);
+		}
+		m_notesFramesMap.unite(notesMap);
+	}
+	if (docWasChanged)
+	{
+		m_Doc->flag_restartMarksRenumbering = true;
+		m_Doc->setNotesChanged(true);
+	}
+}
+
+void PageItem_TextFrame::notesFramesLayout()
+{
+	foreach (PageItem_NoteFrame* nF, m_notesFramesMap.keys())
+	{
+		if (nF == NULL)
+			continue;
+		if (nF->deleteIt)
+			continue;
+		if (nF->isEndNotesFrame() && m_Doc->flag_updateEndNotes)
+			m_Doc->updateEndNotesFrameContent(nF);
+		nF->invalid = true;
+		nF->layout();
+	}
+}
+
+int PageItem_TextFrame::removeMarksFromText(bool doUndo)
+{
+	int num = 0;
+	if (!isNoteFrame())
+	{
+		TextNote* note = selectedNoteMark(true);
+		while (note != NULL)
+		{
+			if (doUndo && UndoManager::undoEnabled())
+				m_Doc->setUndoDelNote(note);
+			if (note->isEndNote())
+				m_Doc->flag_updateEndNotes = true;
+			m_Doc->deleteNote(note);
+			note = selectedNoteMark(true);
+			++num;
+		}
+	}
+	
+	Mark* mrk = selectedMark(true);
+	while (mrk != NULL)
+	{
+		Q_ASSERT(!mrk->isNoteType());
+		if (doUndo)
+			m_Doc->setUndoDelMark(mrk);
+		m_Doc->eraseMark(mrk, true, this);
+		mrk = selectedMark(true);
+		++num;
+	}
+	return num;
+}
+
+PageItem_NoteFrame *PageItem_TextFrame::itemNoteFrame(NotesStyle *nStyle)
+{
+	foreach (PageItem_NoteFrame* nF, m_notesFramesMap.keys())
+		if (nF->notesStyle() == nStyle)
+			return nF;
+	return NULL;
+}
+
+void PageItem_TextFrame::setNoteFrame(PageItem_NoteFrame *nF)
+{
+	 m_notesFramesMap.insert(nF, nF->notesList());
 }
 
 void PageItem_TextFrame::setMaxY(double y)

Modified: trunk/Scribus/scribus/pageitem_textframe.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/pageitem_textframe.h
==============================================================================
--- trunk/Scribus/scribus/pageitem_textframe.h (original)
+++ trunk/Scribus/scribus/pageitem_textframe.h Sat Oct 27 15:56:36 2012
@@ -29,9 +29,14 @@
 
 #include "scribusapi.h"
 #include "pageitem.h"
+#include "marks.h"
+#include "notesstyles.h"
 
+class PageItem_NoteFrame;
 class ScPainter;
 class ScribusDoc;
+
+typedef QMap<PageItem_NoteFrame*, QList<TextNote *> > NotesInFrameMap;
 
 #include "text/nlsconfig.h"
 
@@ -42,6 +47,9 @@
 class ScText;
 class ScStyleRun;
 #endif
+
+//cezaryece: I remove static statement and made it public as this function is used also by PageItem_NoteFrame
+double calculateLineSpacing (const ParagraphStyle &style, PageItem *item);
 
 class SCRIBUS_API PageItem_TextFrame : public PageItem
 {
@@ -68,15 +76,25 @@
 	void ExpandSel(int dir, int oldPos);
 	void deselectAll();
 	
-	virtual void invalidateLayout();
+	//for speed up updates when changed was only one frame from chain
+	virtual void invalidateLayout(bool wholeChain);
+	using PageItem::invalidateLayout;
 	virtual void layout();
+	//return true if all previouse frames from chain are valid (including that one)
+	bool isValidChainFromBegin();
+	//simplify conditions checking if frame is in chain
+	//FIX: use it in other places
+	bool isInChain() { return ((prevInChain() != NULL) || (nextInChain() != NULL)); }
 
 	double columnWidth();
 #ifdef NLS_PROTO
 	int firstTextItem() const { return itemText.firstFrameItem; }
 	int lastTextItem() const { return itemText.lastFrameItem; }
 #endif
+	//enable/disable marks inserting actions depending on editMode
+	void togleEditModeActions();
 	QRegion availableRegion() { return m_availableRegion; }
+
 protected:
 	QRegion calcAvailableRegion();
 	QRegion m_availableRegion;
@@ -116,15 +134,44 @@
 	QMap<QString,StoryText> shadows;
 	bool checkKeyIsShortcut(QKeyEvent *k);
 	
+private slots:
+	void slotInvalidateLayout();
+
+public:
+	//for footnotes/endnotes
+	bool hasMark(NotesStyle* NS = NULL);
+	bool hasNoteFrame(NotesStyle* NS, bool inChain = false);
+	//bool hasNoteFrame(PageItem_NoteFrame* nF) { return m_notesFramesMap.contains(nF); }
+	void delAllNoteFrames(bool doUpdate = false);
+	void removeNoteFrame(PageItem_NoteFrame* nF) { m_notesFramesMap.remove(nF); }
+	//layout notes frames /updates endnotes frames content if m_Doc->flag_updateEndNotes is set/
+	void notesFramesLayout();
+	//removing all marsk from text, returns number of removed marks
+	int removeMarksFromText(bool doUndo);
+	//return note frame for given notes style if current text frame has notes marks with this style
+	PageItem_NoteFrame* itemNoteFrame(NotesStyle* nStyle);
+	//list all notes frames for current text frame /with endnotes frames if endnotes marks are in that frame/
+	QList<PageItem_NoteFrame*> notesFramesList() { return m_notesFramesMap.keys(); }
+	//list of notes inserted by current text frame into given noteframe
+	QList<TextNote*> notesList(PageItem_NoteFrame* nF) { return m_notesFramesMap.value(nF); }
+	//insert note frame to list with empty notes list
+	void setNoteFrame(PageItem_NoteFrame* nF);
+	void invalidateNotesFrames();
+
+private:
+	NotesInFrameMap m_notesFramesMap;
+	NotesInFrameMap updateNotesFrames(QMap<int, Mark*> noteMarksPosMap); //update notes frames content
+	void updateNotesMarks(NotesInFrameMap notesMap);
+	Mark* selectedMark(bool onlySelection = true);
+	TextNote* selectedNoteMark(ScText* &hl, bool onlySelection = true);
+	TextNote* selectedNoteMark(bool onlySelection = true);
+protected:
 	// set text frame height to last line of text
 	double maxY;
 	void setMaxY(double y);
 
 public:
 	void setTextFrameHeight();
-
-private slots:
-	void slotInvalidateLayout();
 };
 
 #endif

Modified: trunk/Scribus/scribus/pagestructs.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/pagestructs.h
==============================================================================
--- trunk/Scribus/scribus/pagestructs.h (original)
+++ trunk/Scribus/scribus/pagestructs.h Sat Oct 27 15:56:36 2012
@@ -48,8 +48,11 @@
 	Type_I_II_III,
 	Type_a_b_c,
 	Type_A_B_C,
+	Type_asterix,
 	Type_None=99
 } DocumentSectionType;
+
+typedef DocumentSectionType NumerationType;
 
 struct DocumentSection
 {

Modified: trunk/Scribus/scribus/plugins/fileloader/scribus150format/scribus150format.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/plugins/fileloader/scribus150format/scribus150format.cpp
==============================================================================
--- trunk/Scribus/scribus/plugins/fileloader/scribus150format/scribus150format.cpp (original)
+++ trunk/Scribus/scribus/plugins/fileloader/scribus150format/scribus150format.cpp Sat Oct 27 15:56:36 2012
@@ -12,7 +12,9 @@
 #include "ui/missing.h"
 #include "hyphenator.h"
 #include "langmgr.h"
+#include "notesstyles.h"
 #include "pageitem_latexframe.h"
+#include "pageitem_noteframe.h"
 #include "prefsmanager.h"
 #include "scclocale.h"
 #include "scconfig.h"
@@ -28,6 +30,7 @@
 #include "util.h"
 #include "util_math.h"
 #include "util_color.h"
+#include "util_text.h"
 #include "scgzfile.h"
 #ifdef HAVE_OSG
 	#include "pageitem_osgframe.h"
@@ -36,6 +39,7 @@
 #include "pageitem_regularpolygon.h"
 #include "pageitem_arc.h"
 #include "pageitem_spiral.h"
+#include "pagestructs.h"
 #include <QCursor>
 // #include <QDebug>
 #include <QFileInfo>
@@ -379,6 +383,26 @@
 		if (tagName == "Pattern")
 		{
 			success = readPattern(m_Doc, reader, fileDir);
+			if (!success) break;
+		}
+		if (tagName == "NotesStyles")
+		{
+			success = readNotesStyles(m_Doc, reader);
+			if (!success) break;
+		}
+		if (tagName == "NotesFrames")
+		{
+			success = readNotesFrames(reader);
+			if (!success) break;
+		}
+		if (tagName == "Notes")
+		{
+			success = readNotes(m_Doc, reader);
+			if (!success) break;
+		}
+		if (tagName == "Marks")
+		{
+			success = readMarks(m_Doc, reader);
 			if (!success) break;
 		}
 	}
@@ -859,6 +883,26 @@
 			success = readPattern(m_Doc, reader, fileDir);
 			if (!success) break;
 		}
+		if (tagName == "NotesStyles")
+		{
+			success = readNotesStyles(m_Doc, reader);
+			if (!success) break;
+		}
+		if (tagName == "NotesFrames")
+		{
+			success = readNotesFrames(reader);
+			if (!success) break;
+		}
+		if (tagName == "Notes")
+		{
+			success = readNotes(m_Doc, reader);
+			if (!success) break;
+		}
+		if (tagName == "Marks")
+		{
+			success = readMarks(m_Doc, reader);
+			if (!success) break;
+		}
 	}
 
 	if (reader.hasError())
@@ -1182,6 +1226,13 @@
 	QStack< QList<PageItem*> > groupStackP;
 	QStack<int> groupStack2;
 	
+	markeredItemsMap.clear();
+	markeredMarksMap.clear();
+	nsetRangeItemNamesMap.clear();
+	notesFramesData.clear();
+	notesMasterMarks.clear();
+	notesNSets.clear();
+
 	QString f(readSLA(fileName));
 	if (f.isEmpty())
 	{
@@ -1494,6 +1545,26 @@
 			if (!success)
 				break;
 		}
+		if (tagName == "NotesStyles")
+		{
+			success = readNotesStyles(m_Doc, reader);
+			if (!success) break;
+		}
+		if (tagName == "NotesFrames")
+		{
+			success = readNotesFrames(reader);
+			if (!success) break;
+		}
+		if (tagName == "Notes")
+		{
+			success = readNotes(m_Doc, reader);
+			if (!success) break;
+		}
+		if (tagName == "Marks")
+		{
+			success = readMarks(m_Doc, reader);
+			if (!success) break;
+		}
 	}
 
 	if (reader.hasError())
@@ -1805,6 +1876,8 @@
 				gItem->groupItemList = gpL;
 		}
 	}
+	//update names to pointers
+	updateNames2Ptr();
 	
 	// reestablish first/lastAuto
 	m_Doc->FirstAuto = m_Doc->LastAuto;
@@ -2397,7 +2470,6 @@
 		}
 	}
 
-
 	static const QString SHORTCUT("SHORTCUT");
 	if (attrs.hasAttribute(SHORTCUT))
 		newStyle.setShortcut(attrs.valueAsString(SHORTCUT));
@@ -3104,6 +3176,167 @@
 	return !reader.hasError();
 }
 
+bool Scribus150Format::readNotesStyles(ScribusDoc* doc, ScXmlStreamReader& reader)
+{
+	QStringRef tagName = reader.name();
+	while(!reader.atEnd() && !reader.hasError())
+	{
+		reader.readNext();
+		if (reader.isEndElement() && reader.name() == tagName)
+			break;
+		//read notes styles
+		if (reader.isStartElement() && reader.name() == "notesStyle")
+		{
+			ScXmlStreamAttributes attrs = reader.scAttributes();
+			NotesStyle NS;
+			NS.setName(attrs.valueAsString("Name"));
+			NS.setStart(attrs.valueAsInt("Start"));
+			NS.setEndNotes(attrs.valueAsBool("Endnotes"));
+			QString type = attrs.valueAsString("Type");
+			if (type == "Type_1_2_3")
+				NS.setType(Type_1_2_3);
+			else if (type == "Type_i_ii_iii")
+				NS.setType(Type_i_ii_iii);
+			else if (type == "Type_I_II_III")
+				NS.setType(Type_I_II_III);
+			else if (type == "Type_a_b_c")
+				NS.setType(Type_a_b_c);
+			else if (type == "Type_A_B_C")
+				NS.setType(Type_A_B_C);
+			else if (type == "Type_asterix")
+				NS.setType(Type_asterix);
+			else //if (type == "Type_None")
+				NS.setType(Type_None);
+			NS.setRange((NumerationRange) attrs.valueAsInt("Range"));
+			NS.setPrefix(attrs.valueAsString("Prefix"));
+			NS.setSuffix(attrs.valueAsString("Suffix"));
+			NS.setAutoNotesHeight(attrs.valueAsBool("AutoHeight"));
+			NS.setAutoNotesWidth(attrs.valueAsBool("AutoWidth"));
+			NS.setAutoRemoveEmptyNotesFrames(attrs.valueAsBool("AutoRemove"));
+			NS.setAutoWeldNotesFrames(attrs.valueAsBool("AutoWeld"));
+			NS.setSuperscriptInNote(attrs.valueAsBool("SuperNote"));
+			NS.setSuperscriptInMaster(attrs.valueAsBool("SuperMaster"));
+			NS.setMarksCharStyle("");
+			NS.setNotesParStyle("");
+			QString name;
+			name = attrs.valueAsString("MarksStyle");
+			if (!name.isEmpty())
+				NS.setMarksCharStyle(name);
+			name = attrs.valueAsString("NotesStyle");
+			if (!name.isEmpty())
+				NS.setNotesParStyle(name);
+
+			m_Doc->newNotesStyle(NS);
+		}
+	}
+	return !reader.hasError();
+}
+
+bool Scribus150Format::readNotesFrames(ScXmlStreamReader& reader)
+{
+	notesFramesData.clear();
+	QStringRef tagName = reader.name();
+	while(!reader.atEnd() && !reader.hasError())
+	{
+		reader.readNext();
+		if (reader.isEndElement() && reader.name() == tagName)
+			break;
+		if (reader.isStartElement())
+		{
+			ScXmlStreamAttributes attrs = reader.scAttributes();
+			NoteFrameData eF;
+			eF.NSname = attrs.valueAsString("NSname");
+			eF.myID = attrs.valueAsInt("myID");
+			if (reader.name() == "ENDNOTEFRAME")
+			{
+				eF.index = attrs.valueAsInt("index");
+				eF.NSrange = (NumerationRange) attrs.valueAsInt("range");
+				eF.itemID = attrs.valueAsInt("ItemID");
+			}
+			if (reader.name() == "FOOTNOTEFRAME")
+				eF.itemID = attrs.valueAsInt("MasterID");
+			notesFramesData.append(eF);
+		}
+	}
+	return !reader.hasError();
+}
+
+bool Scribus150Format::readNotes(ScribusDoc* doc, ScXmlStreamReader& reader)
+{
+	//read notes
+	QStringRef tagName = reader.name();
+	while(!reader.atEnd() && !reader.hasError())
+	{
+		reader.readNext();
+		if (reader.isEndElement() && reader.name() == tagName)
+			break;
+		if (reader.isStartElement() && reader.name() == "Note")
+		{
+			ScXmlStreamAttributes attrs = reader.scAttributes();
+			TextNote* note = m_Doc->newNote(NULL);
+			note->setSaxedText(attrs.valueAsString("Text"));
+			//temporaly insert names of master mark and notes style into maps with note pointer
+			//will be resolved to pointers by updateNames2Ptr() after all will read
+			notesMasterMarks.insert(attrs.valueAsString("Master"), note);
+			notesNSets.insert(note, attrs.valueAsString("NStyle"));
+		}
+	}
+	return !reader.hasError();
+}
+
+bool Scribus150Format::readMarks(ScribusDoc* doc, ScXmlStreamReader& reader)
+{
+	QStringRef tagName = reader.name();
+	while(!reader.atEnd() && !reader.hasError())
+	{
+		reader.readNext();
+		if (reader.isEndElement() && reader.name() == tagName)
+			break;
+		if(reader.isStartElement() && reader.name() == "Mark")
+		{
+			ScXmlStreamAttributes attrs = reader.scAttributes();
+
+			QString label = "";
+			if (attrs.hasAttribute("label"))
+				label = attrs.valueAsString("label");
+
+			MarkType type = MARKNoType;
+			if (attrs.hasAttribute("type"))
+				type = (MarkType) attrs.valueAsInt("type");
+
+			if (label != "" && type != MARKNoType)
+			{
+				Mark* mark = doc->newMark();
+				mark->label=attrs.valueAsString("label");
+				mark->setType(type);
+
+				if (type == MARKVariableTextType && attrs.hasAttribute("str"))
+					mark->setString(attrs.valueAsString("str"));
+				if (type == MARK2ItemType && attrs.hasAttribute("ItemID"))
+				{
+					//QString itemName = attrs.valueAsString("itemName");
+					markeredItemsMap.insert(mark, attrs.valueAsInt("ItemID"));
+				}
+				if (type == MARK2MarkType && attrs.hasAttribute("MARKlabel"))
+				{
+					QString mark2Label = attrs.valueAsString("MARKlabel");
+					MarkType mark2Type = (MarkType) attrs.valueAsInt("MARKtype");
+					Mark* mark2 = doc->getMarkDefinied(mark2Label, mark2Type);
+					if (mark2 != NULL) //mark is not defined yet, insert into temp list for update to pointers later
+						mark->setMark(mark2);
+					else
+					{
+						QMap<QString, MarkType> mark2map;
+						mark2map.insert(mark2Label, mark2Type);
+						markeredMarksMap.insert(mark, mark2map);
+					}
+				}
+			}
+		}
+	}
+	return !reader.hasError();
+}
+
 bool Scribus150Format::readSections(ScribusDoc* doc, ScXmlStreamReader& reader)
 {
 	QStringRef tagName = reader.name();
@@ -3564,6 +3797,60 @@
 				doc->Items = DItems;
 			}
 		}
+		if (tName == "MARK")
+		{
+			if (newItem->asTextFrame())
+			{
+				QString l = tAtt.valueAsString("label");
+				MarkType t = (MarkType) tAtt.valueAsInt("type");
+				Mark* mark = NULL;
+				if (m_Doc->isLoading())
+				{
+					mark = m_Doc->getMarkDefinied(l, t);
+				}
+				else
+				{	//doc is not loading so it is copy/paste task
+					if (t == MARKVariableTextType)
+						mark = m_Doc->getMarkDefinied(l, t);
+					else
+					{
+						//create copy of mark
+						Mark* oldMark = m_Doc->getMarkDefinied(l, t);
+						if (oldMark == NULL)
+						{
+							qWarning() << "wrong copy of oldMark";
+							mark = m_Doc->newMark();
+							mark->setType(t);
+						}
+						else
+						{
+							mark = m_Doc->newMark(oldMark);
+							getUniqueName(l,doc->marksLabelsList(t), "_");
+						}
+						mark->label = l;
+						if (t == MARKNoteMasterType)
+						{  //create copy of note
+							TextNote* old = mark->getNotePtr();
+							TextNote* note = m_Doc->newNote(old->notesStyle());
+							mark->setNotePtr(note);
+							note->setMasterMark(mark);
+							note->setSaxedText(old->saxedText());
+							m_Doc->setNotesChanged(true);
+						}
+					}
+				}
+				if (mark == NULL)
+					qDebug() << "Undefinied mark label ["<< l << "] type " << t;
+				else
+				{
+					//set pointer to item holds mark in his text
+					if (t == MARKAnchorType)
+						mark->setItemPtr(newItem);
+					mark->OwnPage = newItem->OwnPage;
+					newItem->itemText.insertMark(mark, newItem->itemText.length());
+				}
+			}
+		}
 		if (tName == "WeldEntry")
 		{
 			PageItem::weldingInfo wInf;
@@ -4038,6 +4325,7 @@
 	bool isGroupFlag = attrs.valueAsBool("isGroupControl", 0);
 	if (isGroupFlag)
 		pt = PageItem::Group;
+	bool isNoteFrameFlag = attrs.valueAsBool("isNoteFrame", 0);
 	double xf, yf;
 	double x   = attrs.valueAsDouble("XPOS");
 	double y   = attrs.valueAsDouble("YPOS");
@@ -4160,7 +4448,7 @@
 			currItem->OwnPage = pagenr;
 		break;
 	case PageItem::TextFrame:
-		z = doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, x, y, w, h, pw, CommonStrings::None, Pcolor, true);
+		z = doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, x, y, w, h, pw, CommonStrings::None, Pcolor, true, isNoteFrameFlag);
 		currItem = doc->Items->at(z);
 		if (pagenr > -2) 
 			currItem->OwnPage = pagenr;
@@ -4340,10 +4628,10 @@
 		}
 	}
 	currItem->setRotation( attrs.valueAsDouble("ROT", 0.0) );
-	currItem->setTextToFrameDist(attrs.valueAsDouble("EXTRA", 1.0),
-								attrs.valueAsDouble("REXTRA", 1.0),
-								attrs.valueAsDouble("TEXTRA", 1.0),
-								attrs.valueAsDouble("BEXTRA", 1.0));
+	currItem->setTextToFrameDist(attrs.valueAsDouble("EXTRA", 0.0),
+								attrs.valueAsDouble("REXTRA", 0.0),
+								attrs.valueAsDouble("TEXTRA", 0.0),
+								attrs.valueAsDouble("BEXTRA", 0.0));
 	currItem->setFirstLineOffset(static_cast<FirstLineOffsetPolicy>(attrs.valueAsInt("FLOP")));
 
 	currItem->PLineArt  = Qt::PenStyle(attrs.valueAsInt("PLINEART", 0));
@@ -5205,6 +5493,13 @@
 	WeldItems.clear();
 	WeldID.clear();
 
+	markeredItemsMap.clear();
+	markeredMarksMap.clear();
+	nsetRangeItemNamesMap.clear();
+	notesFramesData.clear();
+	notesMasterMarks.clear();
+	notesNSets.clear();
+
  	QString f(readSLA(fileName));
 	if (f.isEmpty())
 	{
@@ -5961,6 +6256,14 @@
 	QString pageName;
 	int counter = 0;
 	int counter2 = 0;
+
+	markeredItemsMap.clear();
+	markeredMarksMap.clear();
+	nsetRangeItemNamesMap.clear();
+	notesFramesData.clear();
+	notesMasterMarks.clear();
+	notesNSets.clear();
+
 	QString f(readSLA(fileName));
 	if (f.isEmpty())
 		return false;
@@ -6001,3 +6304,147 @@
 	*num2 = counter2;
 	return success;
 }
+
+void Scribus150Format::updateNames2Ptr() //after document load - items pointers should be updated
+{
+	if (!markeredItemsMap.isEmpty())
+	{
+		QMap<Mark*, int>::Iterator markIt;
+		QMap<Mark*, int>::Iterator end = markeredItemsMap.end();
+		for (markIt = markeredItemsMap.begin(); markIt != end; ++markIt)
+		{
+			Mark* mrk = markIt.key();
+			int ItemID = markIt.value();
+			if (LinkID.contains(ItemID))
+			{
+				mrk->setItemPtr(LinkID[ItemID]);
+				mrk->setString(QString("%1").arg(mrk->getItemPtr()->OwnPage +1));
+			}
+			else
+			{
+				qWarning() << "Scribus150Format::updateNames2Ptr() : wrong mark [" << mrk->label << "] data - item [" << ItemID << "] not exists - DELETING MARK";
+				if (!m_Doc->eraseMark(mrk, true))
+					qWarning() << "Erase mark [" << mrk->label << "] failed - was it definied?";
+			}
+		}
+		markeredItemsMap.clear();
+	}
+	if (!markeredMarksMap.isEmpty())
+	{
+		QMap<Mark*,QMap<QString, MarkType> >::iterator markIt;
+		QMap<Mark*,QMap<QString, MarkType> >::iterator end = markeredMarksMap.end();
+		for (markIt = markeredMarksMap.begin(); markIt != end; ++markIt)
+		{
+			Mark* mark = markIt.key();
+			QMap<QString, MarkType> mark2map = markIt.value();
+			QString label2 = mark2map.begin().key();
+			MarkType type2 = mark2map.begin().value();
+			Mark* mark2 = m_Doc->getMarkDefinied(label2, type2);
+			if (mark2 != NULL)
+			{
+				mark->setMark(mark2);
+			}
+			else
+			{
+				qWarning() << "Scribus150Format::updateNames2Ptr() : wrong mark [" << mark->label << "] data - pointed mark name [" << label2 << "] not exists - DELETING MARK";
+				if (!m_Doc->eraseMark(mark, true))
+					qWarning() << "Erase mark [" << mark->label << "] failed - was it definied?";
+
+			}
+		}
+		markeredMarksMap.clear();
+	}
+
+	//update endnotes frames pointers
+	if (!notesFramesData.isEmpty())
+	{
+		for (int i = 0; i < notesFramesData.count(); ++i)
+		{
+			NoteFrameData eF = notesFramesData.at(i);
+			NotesStyle* NS = m_Doc->getNotesStyle(eF.NSname);
+			if (NS != NULL)
+			{
+				PageItem* item = LinkID.value(eF.myID);
+				if ((item != NULL) && item->isNoteFrame())
+				{
+					item->asNoteFrame()->setNS(NS);
+					if (NS->isEndNotes())
+					{
+						if (eF.NSrange == NSRdocument)
+							m_Doc->setEndNoteFrame(item->asNoteFrame(), (void*) NULL);
+						else if (eF.NSrange == NSRpage)
+							m_Doc->setEndNoteFrame(item->asNoteFrame(), (void*) m_Doc->DocPages.at(eF.index));
+						else if (eF.NSrange == NSRsection)
+							m_Doc->setEndNoteFrame(item->asNoteFrame(), m_Doc->getSectionKeyForPageIndex(eF.index));
+						else if (eF.NSrange == NSRstory)
+							m_Doc->setEndNoteFrame(item->asNoteFrame(), (void*) LinkID.value(eF.itemID));
+					}
+					else
+					{
+						PageItem* master = LinkID.value(eF.itemID);
+						item->asNoteFrame()->setMaster(master);
+						master->asTextFrame()->setNoteFrame(item->asNoteFrame());
+						//FIX welding with note frame
+						PageItem::weldingInfo wInf;
+						for (int i = 0 ; i < master->weldList.count(); i++)
+						{
+							wInf = master->weldList.at(i);
+							if (wInf.weldID == eF.myID)
+							{
+								master->weldList[i].weldItem = item;
+								break;
+							}
+						}
+					}
+				}
+				else
+					qDebug() << "Scribus150Format::updateNames2Ptr() : update end frames pointers - item is not note frame or name is wrong";
+			}
+		}
+	}
+	//update pointers to notes in master notes marks
+	if (!notesMasterMarks.isEmpty())
+	{
+		assert(!m_Doc->marksList().isEmpty() && !m_Doc->notesList().isEmpty());
+		QMap<QString, TextNote*>::Iterator it;
+		QMap<QString, TextNote*>::Iterator end = notesMasterMarks.end();
+		for (it = notesMasterMarks.begin(); it != end; ++it)
+		{
+			TextNote* note = it.value();
+			assert(note != NULL);
+			QString mrkLabel = it.key();
+			Mark* mrk = m_Doc->getMarkDefinied(mrkLabel, MARKNoteMasterType);
+			if (mrk == NULL)
+			{
+				qWarning() << "Scribus150Format::updateNames2Ptr() : cannot find master mark ("<<mrkLabel <<") for note - note will be deleted";
+				m_Doc->deleteNote(note);
+				continue;
+			}
+			note->setMasterMark(mrk);
+			mrk->setNotePtr(note);
+		}
+		notesMasterMarks.clear();
+	}
+	if (!notesNSets.isEmpty())
+	{
+		assert(!m_Doc->notesList().isEmpty());
+		QMap<TextNote*, QString>::iterator it;
+		QMap<TextNote*, QString>::iterator end = notesNSets.end();
+		for (it = notesNSets.begin(); it != end; ++it)
+		{
+			TextNote* note = it.key();
+			assert(note != NULL);
+			QString nsLabel = it.value();
+			NotesStyle* ns = m_Doc->getNotesStyle(nsLabel);
+			if (ns != NULL)
+				note->setNotesStyle(ns);
+			if (note->notesStyle() == NULL)
+			{
+				qWarning() << "Scribus150Format::updateNames2Ptr()  : cannot find notes style ("<<nsLabel <<") for note - note will be deleted";
+				m_Doc->deleteNote(note);
+				continue;
+			}
+		}
+		notesNSets.clear();
+	}
+}

Modified: trunk/Scribus/scribus/plugins/fileloader/scribus150format/scribus150format.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/plugins/fileloader/scribus150format/scribus150format.h
==============================================================================
--- trunk/Scribus/scribus/plugins/fileloader/scribus150format/scribus150format.h (original)
+++ trunk/Scribus/scribus/plugins/fileloader/scribus150format/scribus150format.h Sat Oct 27 15:56:36 2012
@@ -9,6 +9,7 @@
 
 #include "pluginapi.h"
 #include "loadsaveplugin.h"
+#include "notesstyles.h"
 #include "scfonts.h"
 #include "scribusstructs.h"
 #include "styles/styleset.h"
@@ -125,6 +126,27 @@
 		bool readPrinterOptions(ScribusDoc* doc, ScXmlStreamReader& reader);
 		bool readSections(ScribusDoc* doc, ScXmlStreamReader& reader);
 		bool readTableOfContents(ScribusDoc* doc, ScXmlStreamReader& reader);
+		bool readNotes(ScribusDoc* doc, ScXmlStreamReader& reader);
+		bool readNotesStyles(ScribusDoc* doc, ScXmlStreamReader& reader);
+		bool readNotesFrames(ScXmlStreamReader &reader);
+		bool readMarks(ScribusDoc* doc, ScXmlStreamReader& reader);
+
+		//lists of items and marks with names only, which need update to pointers
+		QMap<Mark*, int> markeredItemsMap;
+		QMap<Mark*, QMap<QString, MarkType> > markeredMarksMap;
+		QMap<QString, int> nsetRangeItemNamesMap;
+		QMap<QString, TextNote*> notesMasterMarks;
+		QMap<TextNote*, QString> notesNSets;
+		struct NoteFrameData {
+			QString NSname;
+			int myID;
+			int itemID;
+			int index;
+			NumerationRange NSrange;
+		};
+		QList<NoteFrameData> notesFramesData;
+		
+		void updateNames2Ptr(); //after document load items pointers should be updated in markeredItemList
 
 		PageItem* pasteItem(ScribusDoc *doc, ScXmlStreamAttributes& attrs, const QString& baseDir, int pagenr = -2 /* currentPage*/);
 
@@ -151,6 +173,10 @@
 		void writePdfOptions(ScXmlStreamWriter& docu);
 		void writeDocItemAttributes(ScXmlStreamWriter& docu);
 		void writeTOC(ScXmlStreamWriter& docu);
+		void writeMarks(ScXmlStreamWriter & docu);
+		void writeNotesStyles(ScXmlStreamWriter & docu);
+		void writeNotesFrames(ScXmlStreamWriter & docu);
+		void writeNotes(ScXmlStreamWriter & docu);
 		void writePageSets(ScXmlStreamWriter& docu);
 		void writeSections(ScXmlStreamWriter& docu);
 		void writePatterns(ScXmlStreamWriter& docu, const QString& baseDir, bool part = false, Selection* selection = 0);

Modified: trunk/Scribus/scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp
==============================================================================
--- trunk/Scribus/scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp (original)
+++ trunk/Scribus/scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp Sat Oct 27 15:56:36 2012
@@ -20,6 +20,7 @@
 #include "scribusdoc.h"
 #include "scribusview.h"
 #include "hyphenator.h"
+#include "notesstyles.h"
 #include "pageitem_latexframe.h"
 #ifdef HAVE_OSG
 	#include "pageitem_osgframe.h"
@@ -28,6 +29,7 @@
 #include "pageitem_arc.h"
 #include "pageitem_spiral.h"
 #include "pageitem_table.h"
+#include "pageitem_noteframe.h"
 
 #include "units.h"
 #include "util.h"
@@ -71,6 +73,9 @@
 		emG.append(currItem);
 		if ((currItem->asTextFrame()) || (currItem->asPathText()))
 		{
+			//for notes frames text should not be saved
+			if (currItem->isNoteFrame())
+				continue;
 			for (int e = currItem->firstInFrame(); e <= currItem->lastInFrame(); ++e)
 			{
 				uint chr = currItem->itemText.text(e).unicode();
@@ -386,6 +391,10 @@
 	writePdfOptions(docu);
 	writeDocItemAttributes(docu);
 	writeTOC(docu);
+	writeMarks(docu);
+	writeNotesStyles(docu);
+	writeNotesFrames(docu);
+	writeNotes(docu);
 	writePageSets(docu);
 	writeSections(docu);
 	writePatterns(docu, fileDir);
@@ -1188,6 +1197,9 @@
 			case Type_A_B_C:
 				docu.writeAttribute("Type", "Type_A_B_C");
 				break;
+			case Type_asterix:
+				docu.writeAttribute("Type", "Type_asterix");
+				break;
 			case Type_None:
 				docu.writeAttribute("Type", "Type_None");
 				break;
@@ -1201,6 +1213,154 @@
 	docu.writeEndElement();
 }
 
+void Scribus150Format::writeMarks(ScXmlStreamWriter & docu)
+{
+	//write list of definied marks to SLA
+	if (m_Doc->marksList().isEmpty())
+		return;
+	docu.writeStartElement("Marks");
+	foreach(Mark* mrk, m_Doc->marksList())
+	{
+		if (mrk->isType(MARKNoteFrameType))
+			continue;
+		docu.writeEmptyElement("Mark");
+		docu.writeAttribute("label", mrk->label);
+		docu.writeAttribute("type", mrk->getType());
+		if (mrk->isType(MARK2ItemType) && mrk->hasItemPtr())
+		{
+			const PageItem* item = mrk->getItemPtr();
+			assert(item != NULL);
+			docu.writeAttribute("ItemID", qHash(item));
+			//docu.writeAttribute("itemName", item->itemName());
+		}
+		else if (mrk->isType(MARKVariableTextType) && mrk->hasString())
+			docu.writeAttribute("str", mrk->getString());
+		else if (mrk->isType(MARK2MarkType) && mrk->hasMark())
+		{
+			QString label;
+			MarkType type;
+			mrk->getMark(label, type);
+			docu.writeAttribute("MARKlabel", label);
+			docu.writeAttribute("MARKtype", type);
+		}
+	}
+	docu.writeEndElement();
+}
+
+void Scribus150Format::writeNotesStyles(ScXmlStreamWriter & docu)
+{
+	//write notes styles
+	docu.writeStartElement("NotesStyles");
+	QList<NotesStyle*>::Iterator itNS;
+	QList<NotesStyle*>::Iterator end = m_Doc->m_docNotesStylesList.end();
+	for (itNS = m_Doc->m_docNotesStylesList.begin(); itNS != end; ++itNS)
+	{
+		NotesStyle* NS = (*itNS);
+		docu.writeEmptyElement("notesStyle");
+		docu.writeAttribute("Name", NS->name());
+		docu.writeAttribute("Start", NS->start());
+		docu.writeAttribute("Endnotes", NS->isEndNotes());
+		switch (NS->getType())
+		{
+			case Type_1_2_3:
+				docu.writeAttribute("Type", "Type_1_2_3");
+				break;
+			case Type_i_ii_iii:
+				docu.writeAttribute("Type", "Type_i_ii_iii");
+				break;
+			case Type_I_II_III:
+				docu.writeAttribute("Type", "Type_I_II_III");
+				break;
+			case Type_a_b_c:
+				docu.writeAttribute("Type", "Type_a_b_c");
+				break;
+			case Type_A_B_C:
+				docu.writeAttribute("Type", "Type_A_B_C");
+				break;
+			case Type_asterix:
+				docu.writeAttribute("Type", "Type_asterix");
+				break;
+			case Type_None:
+				docu.writeAttribute("Type", "Type_None");
+				break;
+		}
+		docu.writeAttribute("Range", (int) NS->range());
+		docu.writeAttribute("Prefix", NS->prefix());
+		docu.writeAttribute("Suffix", NS->suffix());
+		docu.writeAttribute("AutoHeight", NS->isAutoNotesHeight());
+		docu.writeAttribute("AutoWidth", NS->isAutoNotesWidth());
+		docu.writeAttribute("AutoRemove", NS->isAutoRemoveEmptyNotesFrames());
+		docu.writeAttribute("AutoWeld", NS->isAutoWeldNotesFrames());
+		docu.writeAttribute("SuperNote", NS->isSuperscriptInNote());
+		docu.writeAttribute("SuperMaster", NS->isSuperscriptInMaster());
+		docu.writeAttribute("MarksStyle", NS->marksChStyle());
+		docu.writeAttribute("NotesStyle", NS->notesParStyle());
+	}
+	docu.writeEndElement();
+}
+
+void Scribus150Format::writeNotesFrames(ScXmlStreamWriter &docu)
+{
+	docu.writeStartElement("NotesFrames");
+
+	QList<PageItem_NoteFrame*> NFList;
+	foreach (NotesStyle* NS, m_Doc->m_docNotesStylesList)
+		NFList.append(m_Doc->listNotesFrames(NS));
+
+	for (int it = 0; it < NFList.count(); ++it)
+	{
+		PageItem_NoteFrame* nF = NFList.at(it);
+		NotesStyle* NS = nF->notesStyle();
+		if (NS->isEndNotes())
+		{
+			docu.writeEmptyElement("ENDNOTEFRAME");
+			docu.writeAttribute("NSname", NS->name());
+			docu.writeAttribute("range", (int) NS->range());
+			docu.writeAttribute("myID", qHash(nF));
+			//docu.writeAttribute("name", nF->itemName());
+			
+			rangeItem rI = m_Doc->m_docEndNotesFramesMap.value(nF);
+			if (NS->range() == NSRsection)
+				docu.writeAttribute("index", rI.sectionIndex);
+			else if (NS->range() == NSRpage)
+				docu.writeAttribute("index", rI.page->pageNr());
+			else if (NS->range() == NSRstory)
+				docu.writeAttribute("ItemID", qHash(rI.firstStoryFrame));
+				//docu.writeAttribute("item", rI.firstStoryFrame->itemName());
+		}
+		else //footnotes frame
+		{
+			docu.writeEmptyElement("FOOTNOTEFRAME");
+			docu.writeAttribute("NSname", NS->name());
+			docu.writeAttribute("myID", qHash(nF));
+			//docu.writeAttribute("name", nF->itemName());
+			docu.writeAttribute("MasterID", qHash(nF->masterFrame()));
+			//docu.writeAttribute("master",nF->masterFrame()->itemName());
+		}
+	}
+	docu.writeEndElement();
+}
+
+void Scribus150Format::writeNotes(ScXmlStreamWriter & docu)
+{
+	//write notes
+	if (m_Doc->notesList().isEmpty())
+		return;
+	docu.writeStartElement("Notes");
+	QList<TextNote*>::const_iterator itTN;
+	QList<TextNote*>::const_iterator end = m_Doc->notesList().end();
+	for (itTN = m_Doc->notesList().begin(); itTN != end; ++itTN)
+	{
+		TextNote* TN = (*itTN);
+		if (TN->masterMark() == NULL)
+			continue;
+		docu.writeEmptyElement("Note");
+		docu.writeAttribute("Master", TN->masterMark()->label);
+		docu.writeAttribute("NStyle", TN->notesStyle()->name());
+		docu.writeAttribute("Text", TN->saxedText());
+	}
+	docu.writeEndElement();
+}
 
 void Scribus150Format::writePageSets(ScXmlStreamWriter & docu) 
 {	
@@ -1350,7 +1510,10 @@
 	CharStyle lastStyle;
 	int lastPos = 0;
 	QString tmpnum;
-	for(int k = 0; k < item->itemText.length(); ++k)
+	int iTLen = item->itemText.length();
+	if (item->isNoteFrame())
+		iTLen = 0;  //used for saving empty endnotes frames, as they will be filled automatically
+	for(int k = 0; k < iTLen; ++k)
 	{
 		const CharStyle& style1(item->itemText.charStyle(k));
 		const QChar ch = item->itemText.text(k);
@@ -1397,6 +1560,13 @@
 			tmpnum.setNum(ch.unicode());
 			docu.writeAttribute("Unicode", tmpnum);
 			docu.writeAttribute("COBJ", item->itemText.object(k)->inlineCharID);
+		}
+		else if (ch == SpecialChars::OBJECT && item->itemText.item(k)->mark != NULL)
+		{
+			Mark* mark = item->itemText.item(k)->mark;
+			docu.writeEmptyElement("MARK");
+			docu.writeAttribute("label", mark->label);
+			docu.writeAttribute("type", mark->getType());
 		}
 		else if (ch == SpecialChars::PARSEP)	// stores also the paragraphstyle for preceding chars
 			putPStyle(docu, item->itemText.paragraphStyle(k), "para");
@@ -1711,6 +1881,9 @@
 			else
 			{
 				docu.writeAttribute("BACKITEM", -1);
+				if (item->isNoteFrame())
+					docu.writeAttribute("isNoteFrame", 1);
+				else
 				writeITEXTs(doc, docu, item);
 			}
 		}
@@ -2137,18 +2310,6 @@
 			}
 			docu.writeEndElement();
 		}
-		//write weld parameter
-		if (item->isWelded())
-		{
-			for (int i = 0 ; i <  item->weldList.count(); i++)
-			{
-				PageItem::weldingInfo wInf = item->weldList.at(i);
-				docu.writeEmptyElement("WeldEntry");
-				docu.writeAttribute("Target", qHash(wInf.weldItem));
-				docu.writeAttribute("WX", wInf.weldPoint.x());
-				docu.writeAttribute("WY", wInf.weldPoint.y());
-			}
-		}
 		docu.writeEndElement();
 	}
 }
@@ -2200,10 +2361,32 @@
 			docu.writeAttribute("PLINEJOIN", item->PLineJoin);
 	}
 	//write weld parameter
+	//write weld parameter
 	if (item->isWelded())
 	{
+		bool isWelded = false;
+		for (int i = 0 ; i <  item->weldList.count(); i++)
+		{
+			PageItem::weldingInfo wInf = item->weldList.at(i);
+			PageItem *pIt = wInf.weldItem;
+			if (pIt == NULL)
+			{
+				qDebug() << "Saving welding info - empty pointer!!!";
+				continue;
+			}
+			if (pIt->isAutoNoteFrame())
+				continue;
+			isWelded = true;
+			docu.writeEmptyElement("WeldEntry");
+			docu.writeAttribute("Target", qHash(wInf.weldItem));
+			docu.writeAttribute("WX", wInf.weldPoint.x());
+			docu.writeAttribute("WY", wInf.weldPoint.y());
+		}
+		if (isWelded)
+		{
 		docu.writeAttribute("isWeldItem", 1);
 		docu.writeAttribute("WeldSource", qHash(item));
+	}
 	}
 	if (item->asRegularPolygon())
 	{

Modified: trunk/Scribus/scribus/plugins/gettext/textfilter/textfilter.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/plugins/gettext/textfilter/textfilter.cpp
==============================================================================
--- trunk/Scribus/scribus/plugins/gettext/textfilter/textfilter.cpp (original)
+++ trunk/Scribus/scribus/plugins/gettext/textfilter/textfilter.cpp Sat Oct 27 15:56:36 2012
@@ -131,7 +131,7 @@
 		{
 			QString tmpText(list[i]);
 			QString tmpText2(tmpText);
-			tmpText2.simplified();
+			tmpText2=tmpText2.simplified();
 			int numberOfWords = tmpText2.count(" ");
 			++numberOfWords;
 			useStyle = NULL;

Modified: trunk/Scribus/scribus/plugins/scriptplugin/scriptercore.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/plugins/scriptplugin/scriptercore.cpp
==============================================================================
--- trunk/Scribus/scribus/plugins/scriptplugin/scriptercore.cpp (original)
+++ trunk/Scribus/scribus/plugins/scriptplugin/scriptercore.cpp Sat Oct 27 15:56:36 2012
@@ -18,6 +18,8 @@
 
 #include "runscriptdialog.h"
 #include "ui/helpbrowser.h"
+#include "ui/marksmanager.h"
+#include "ui/notesstyleseditor.h"
 #include "ui/propertiespalette.h" //TODO Move the calls to this to a signal
 #include "ui/pagepalette.h" //TODO Move the calls to this to a signal
 #include "ui/layers.h" //TODO Move the calls to this to a signal
@@ -170,6 +172,8 @@
 	if (ScMW->HaveDoc)
 	{
 		ScMW->propertiesPalette->setDoc(ScMW->doc);
+		ScMW->marksManager->setDoc(ScMW->doc);
+		ScMW->nsEditor->setDoc(ScMW->doc);
 		ScMW->layerPalette->setDoc(ScMW->doc);
 		ScMW->outlinePalette->setDoc(ScMW->doc);
 		ScMW->outlinePalette->BuildTree();

Modified: trunk/Scribus/scribus/scribus.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/scribus.cpp
==============================================================================
--- trunk/Scribus/scribus/scribus.cpp (original)
+++ trunk/Scribus/scribus/scribus.cpp Sat Oct 27 15:56:36 2012
@@ -100,11 +100,14 @@
 #include "gtgettext.h"
 #include "hyphenator.h"
 #include "langmgr.h"
+#include "marks.h"
+#include "notesstyles.h"
 #include "pageitem_group.h"
 #include "pageitem_imageframe.h"
 #include "pageitem_latexframe.h"
 #include "pageitem_table.h"
 #include "pageitem_textframe.h"
+#include "pageitem_noteframe.h"
 #include "pagesize.h"
 #include "pdflib.h"
 #include "pdfoptions.h"
@@ -164,6 +167,14 @@
 #include "ui/loremipsum.h"
 #include "ui/marginwidget.h"
 #include "ui/margindialog.h"
+#include "ui/mark2item.h"
+#include "ui/mark2mark.h"
+#include "ui/markanchor.h"
+#include "ui/marknote.h"
+#include "ui/markvariabletext.h"
+#include "ui/MarkInsertDlg.h"
+#include "ui/marksmanager.h"
+#include "ui/masterpagepalette.h"
 #include "ui/mergedoc.h"
 #include "ui/movepage.h"
 #include "ui/multipleduplicate.h"
@@ -174,6 +185,7 @@
 #include "ui_nftdialog.h"
 #include "ui/nftwidget.h"
 #include "ui/nodeeditpalette.h"
+#include "ui/notesstyleseditor.h"
 #ifdef HAVE_OSG
 	#include "ui/osgeditor.h"
 	#include <osgDB/ReaderWriter>
@@ -332,7 +344,7 @@
 	PrefsContext *undoPrefs = prefsManager->prefsFile->getContext("undo");
 	undoManager->setUndoEnabled(undoPrefs->getBool("enabled", true));
 	tocGenerator = new TOCGenerator();
-
+	m_marksCount = 0;
 
 	initDefaultValues();
 
@@ -628,6 +640,17 @@
 	connect( styleManager, SIGNAL(paletteShown(bool)), scrActions["editStyles"], SLOT(setChecked(bool)));
 	styleManager->installEventFilter(this);
 
+	// initializing mark`s manager
+	marksManager = new MarksManager(this, "marksManager");
+	connect( scrActions["editMarks"], SIGNAL(toggled(bool)), marksManager, SLOT(setPaletteShown(bool)) );
+	connect( marksManager, SIGNAL(paletteShown(bool)), scrActions["editMarks"], SLOT(setChecked(bool)));
+	marksManager->installEventFilter(this);
+	// initializing notes styles manager
+	nsEditor = new NotesStylesEditor(this, "notesStylesEditor");
+	connect( scrActions["editNotesStyles"], SIGNAL(toggled(bool)), nsEditor, SLOT(setPaletteShown(bool)) );
+	connect( nsEditor, SIGNAL(paletteShown(bool)), scrActions["editNotesStyles"], SLOT(setChecked(bool)));
+	nsEditor->installEventFilter(this);
+
 //	connect(docCheckerPalette, SIGNAL(selectElement(int, int)), this, SLOT(selectItemsFromOutlines(int, int)));
 	connect(docCheckerPalette, SIGNAL(selectElementByItem(PageItem *, bool)), this, SLOT(selectItemsFromOutlines(PageItem *, bool)));
 	connect(docCheckerPalette, SIGNAL(selectElement(PageItem *, bool, int)), this, SLOT(selectItemFromOutlines(PageItem *, bool, int)));
@@ -765,6 +788,8 @@
 //	scrMenuMgr->addMenuItem(scrActions["editGradients"], "Edit", false);
 //	scrMenuMgr->addMenuItem(scrActions["editPatterns"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editStyles"], "Edit", false);
+	scrMenuMgr->addMenuItem(scrActions["editMarks"], "Edit", false);
+	scrMenuMgr->addMenuItem(scrActions["editNotesStyles"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editMasterPages"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editJavascripts"], "Edit", false);
 	scrMenuMgr->setMenuEnabled("EditPasteRecent", false);
@@ -884,6 +909,9 @@
 	scrMenuMgr->addMenuItem(scrActions["itemWeld"], "Item", false);
 	scrMenuMgr->addMenuItem(scrActions["itemEditWeld"], "Item", false);
 
+	scrMenuMgr->addMenuItem(scrActions["editMark"], "Item", false);
+	scrMenuMgr->addMenuItem(scrActions["itemUpdateMarks"], "Item", true);
+
 	//Insert menu
 	scrMenuMgr->createMenu("Insert", ActionManager::defaultMenuNameEntryTranslated("Insert"));
 	scrMenuMgr->addMenuItem(scrActions["insertFrame"], "Insert", false);
@@ -973,6 +1001,14 @@
 
 	scrMenuMgr->addMenuSeparator("Insert");
 	scrMenuMgr->addMenuItem(scrActions["insertSampleText"], "Insert", false);
+	scrMenuMgr->addMenuSeparator("Insert");
+	scrMenuMgr->createMenu("InsertMark", tr("Marks"), "Insert");
+	scrMenuMgr->addMenuItem(scrActions["insertMarkAnchor"], "InsertMark", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarkVariableText"], "InsertMark", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarkItem"], "InsertMark", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMark2Mark"], "InsertMark", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarkNote"], "InsertMark", false);
+//	scrMenuMgr->addMenuItem(scrActions["insertMarkIndex"], "InsertMark", false);
 
 	//Page menu
 	scrMenuMgr->createMenu("Page", ActionManager::defaultMenuNameEntryTranslated("Page"));
@@ -1176,6 +1212,7 @@
 //AV to be replaced with Selection::update and listener in PropertiesPalette
 void ScribusMainWindow::setTBvals(PageItem *currItem)
 {
+	scrActions["editMark"]->setEnabled(false);
 	if (currItem->itemText.length() != 0)
 	{
 //		int ChPos = qMin(currItem->CPos, static_cast<int>(currItem->itemText.length()-1));
@@ -1189,6 +1226,19 @@
 		emit TextStyle(doc->currentStyle);
 		// to go: (av)
 		propertiesPalette->textPal->updateStyle(doc->currentStyle);
+		//check if mark in cursor place and enable editMark action
+		if (doc->appMode == modeEdit && currItem->itemText.cursorPosition() < currItem->itemText.length())
+		{
+			ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+			if (hl->hasMark())
+			{
+				scrActions["editMark"]->setEnabled(true);
+				if ((hl->mark->isType(MARKNoteMasterType) || hl->mark->isType(MARKNoteFrameType)) && (hl->mark->getNotePtr() != NULL))
+					nsEditor->setNotesStyle(hl->mark->getNotePtr()->notesStyle());
+			}
+			else
+				scrActions["editMark"]->setEnabled(false);
+		}
 	}
 }
 
@@ -1229,7 +1279,13 @@
 								ss->set("ETEA", QString("insert_frametext"));
 								ss->set("TEXT_STR", QString(QChar(unicodevalue)));
 								ss->set("START", currItem->itemText.cursorPosition());
-								undoManager->action(currItem, ss);
+								UndoObject * undoTarget = currItem;
+								if (currItem->isNoteFrame())
+								{
+									undoTarget = doc;
+									ss->set("noteframeName", currItem->getUName());
+								}
+								undoManager->action(undoTarget, ss);
 							}
 						}
 						currItem->itemText.insertChars(QString(QChar(unicodevalue)), true);
@@ -1262,7 +1318,13 @@
 									ss->set("ETEA", QString("insert_frametext"));
 									ss->set("TEXT_STR", QString(SpecialChars::SHYPHEN));
 									ss->set("START", currItem->itemText.cursorPosition());
-									undoManager->action(currItem, ss);
+									UndoObject * undoTarget = currItem;
+									if (currItem->isNoteFrame())
+									{
+										undoTarget = doc;
+										ss->set("noteframeName", currItem->getUName());
+									}
+									undoManager->action(undoTarget, ss);
 								}
 							}
 							currItem->itemText.insertChars(QString(SpecialChars::SHYPHEN), true);
@@ -1633,16 +1695,25 @@
 				if (currItem->asImageFrame() && !currItem->locked())
 				{
 					currItem->handleModeEditKey(k, keyrep);
-					slotDocCh(false);
 				}
 //FIXME:av		view->oldCp = currItem->CPos;
-				else if (currItem->itemType() == PageItem::TextFrame)
+				if (currItem->itemType() == PageItem::TextFrame)
 				{
 					bool kr=keyrep;
 					view->canvasMode()->keyPressEvent(k); //Hack for 1.4.x for stopping the cursor blinking while moving about
 					currItem->handleModeEditKey(k, keyrep);
+					if (currItem->isAutoNoteFrame() && currItem->asNoteFrame()->notesList().isEmpty())
+					{
+						if (!currItem->asNoteFrame()->isEndNotesFrame())
+						{
+							currItem->asNoteFrame()->masterFrame()->invalidateLayout(false);
+							currItem->asNoteFrame()->masterFrame()->updateLayout();
+						}
+					}
 					keyrep=kr;
 				}
+				slotDocCh(false);
+				doc->regionsChanged()->update(QRectF());
 			}
 		}
 	}
@@ -2076,6 +2147,8 @@
 		tempView->cmsToolbarButton->setChecked(tempDoc->HasCMS);
 		undoManager->switchStack(tempDoc->DocName);
 		styleManager->setDoc(tempDoc);
+		marksManager->setDoc(tempDoc);
+		nsEditor->setDoc(tempDoc);
 		tocGenerator->setDoc(tempDoc);
 	}
 	undoManager->setUndoEnabled(true);
@@ -2302,6 +2375,8 @@
 	docCheckerPalette->setDoc(doc);
 	tocGenerator->setDoc(doc);
 	styleManager->setDoc(doc);
+	marksManager->setDoc(doc);
+	nsEditor->setDoc(doc);
 	symbolPalette->setDoc(doc);
 	inlinePalette->setDoc(doc);
 	modeToolBar->Angle->setValue(doc->itemToolPrefs().calligrapicPenAngle);
@@ -2334,6 +2409,8 @@
 	updateActiveWindowCaption(doc->DocName);
 // 	scrActions["shade100"]->setChecked(true);
 	propertiesPalette->setDoc(doc);
+	marksManager->setDoc(doc);
+	nsEditor->setDoc(doc);
 	//propertiesPalette->Cpal->displayGradient(0);
 	pagePalette->setView(view);
 	layerPalette->setDoc(doc);
@@ -2474,6 +2551,8 @@
 //	scrActions["editPatterns"]->setEnabled(true);
 //	scrActions["editGradients"]->setEnabled(true);
  	scrActions["editStyles"]->setEnabled(true);
+	scrActions["editMarks"]->setEnabled(true);
+	scrActions["editNotesStyles"]->setEnabled(true);
 	scrActions["editMasterPages"]->setEnabled(true);
 	scrActions["editJavascripts"]->setEnabled(true);
 
@@ -2540,6 +2619,8 @@
 	updateActiveWindowCaption(doc->DocName);
 // 	scrActions["shade100"]->setChecked(true);
 	propertiesPalette->setDoc(doc);
+	nsEditor->setDoc(doc);
+	marksManager->setDoc(doc);
 	symbolPalette->setDoc(doc);
 	inlinePalette->setDoc(doc);
 //	propertiesPalette->Cpal->displayGradient(0);
@@ -2899,6 +2980,8 @@
 		scrActions["toolsCopyProperties"]->setEnabled(true);
 		scrActions["toolsEditWithStoryEditor"]->setEnabled(true);
 		scrActions["insertSampleText"]->setEnabled(true);
+		scrMenuMgr->setMenuEnabled("InsertMark",true);
+
 		if ((currItem->nextInChain() != 0) || (currItem->prevInChain() != 0))
 		{
 			scrActions["itemConvertToBezierCurve"]->setEnabled(false);
@@ -2931,14 +3014,19 @@
 			setTBvals(currItem);
 			scrActions["editSelectAll"]->setEnabled(true);
 			scrActions["editSelectAllOnLayer"]->setEnabled(false);
+			scrMenuMgr->setMenuEnabled("InsertMark",true);
 			charPalette->setEnabled(true, currItem);
 			if (currItem->asTextFrame())
+			{
 				enableTextActions(&scrActions, true, currItem->currentStyle().charStyle().font().scName());
+				currItem->asTextFrame()->togleEditModeActions();
+			}
 			view->horizRuler->setItem(currItem);
 			view->horizRuler->update();
 		}
 		else
 		{
+			scrMenuMgr->setMenuEnabled("InsertMark",false);
 			doc->currentStyle = currItem->itemText.defaultStyle();
 			propertiesPalette->textPal->displayParStyle(doc->currentStyle.parent());
 			propertiesPalette->textPal->displayCharStyle(doc->currentStyle.charStyle().parent());
@@ -3340,6 +3428,20 @@
 		Q_ASSERT(plugin); // all the returned names should represent loaded plugins
 		plugin->changedDoc(doc);
 	}
+	if (m_marksCount != doc->marksList().count() || doc->notesChanged() || doc->flag_updateEndNotes || doc->flag_updateMarksLabels)
+	{
+		bool sendUpdateReqest = false;
+		if (m_marksCount != doc->marksList().count() || doc->flag_updateMarksLabels)
+			sendUpdateReqest = true;
+		m_marksCount = doc->marksList().count();
+		doc->updateMarks(doc->notesChanged());
+		doc->updateChangedEndNotesFrames();
+		if (sendUpdateReqest)
+			emit UpdateRequest(reqMarksUpdate);
+		doc->setNotesChanged(false);
+		doc->flag_updateEndNotes = false;
+		doc->flag_updateMarksLabels = false;
+	}
 }
 
 void ScribusMainWindow::updateRecent(QString fn)
@@ -4161,8 +4263,14 @@
 		for (int azz=0; azz<docItemsCount; ++azz)
 		{
 			PageItem *ite = doc->Items->at(azz);
-			if(ite->nextInChain() == NULL)
+			if((ite->nextInChain() == NULL) && !ite->isNoteFrame())  //do not layout notes frames
 				ite->layout();
+		}
+		if (!doc->marksList().isEmpty())
+		{
+			doc->setLoading(true);
+			doc->updateMarks(true);
+			doc->setLoading(false);
 		}
 		for (QHash<int, PageItem*>::iterator itf = doc->FrameItems.begin(); itf != doc->FrameItems.end(); ++itf)
 		{
@@ -4232,6 +4340,8 @@
 	qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
 	undoManager->setUndoEnabled(true);
 	doc->setModified(false);
+	foreach (NotesStyle* NS, doc->m_docNotesStylesList)
+		doc->updateNotesFramesStyles(NS);
 #ifdef DEBUG_LOAD_TIMES
 	times(&tms2);
 	double ticks = sysconf(_SC_CLK_TCK);
@@ -4310,6 +4420,8 @@
 			view->DrawNew();
 			slotDocCh();
 			styleManager->setDoc(doc);
+			marksManager->setDoc(doc);
+			nsEditor->setDoc(doc);
 		}
 	}
 }
@@ -4725,6 +4837,8 @@
 //		scrActions["editPatterns"]->setEnabled(false);
 //		scrActions["editGradients"]->setEnabled(false);
 		scrActions["editStyles"]->setEnabled(false);
+		scrActions["editMarks"]->setEnabled(false);
+		scrActions["editNotesStyles"]->setEnabled(false);
 		scrActions["editSearchReplace"]->setEnabled(false);
 		scrActions["editMasterPages"]->setEnabled(false);
 		scrActions["editJavascripts"]->setEnabled(false);
@@ -4832,6 +4946,8 @@
 	charPalette->setDoc(0);
 	tocGenerator->setDoc(0);
 	styleManager->setDoc(0);
+	marksManager->setDoc(0);
+	nsEditor->setDoc(0);
 	layerPalette->ClearInhalt();
 	docCheckerPalette->buildErrorList(0);
 	HaveDoc--;
@@ -5148,6 +5264,19 @@
 		{
 			if ((currItem->isSingleSel) && (currItem->isGroup()))
 				return;
+			//do not copy notes frames
+			if (doc->m_Selection->count() ==1 && currItem->isNoteFrame())
+				return;
+			//deselect notesframes
+			Selection tempSelection(*(doc->m_Selection));
+			for (int i = 0; i < doc->m_Selection->count(); ++i)
+			{
+				if (doc->m_Selection->itemAt(i)->isNoteFrame())
+					tempSelection.removeItem(doc->m_Selection->itemAt(i));
+			}
+			if (tempSelection.count() < doc->m_Selection->count())
+				*(doc->m_Selection) = tempSelection;
+
 			ScriXmlDoc ss;
 			QString BufferS = ss.WriteElem(doc, doc->m_Selection);
 			if (!internalCopy)
@@ -5194,7 +5323,12 @@
 				currItem = selItem->asTextFrame();
 			assert(currItem != NULL);
 			if (currItem->HasSel)
+			{
+				//removing marks and notes from selected text
+//				if (currItem->isTextFrame() && !currItem->asTextFrame()->removeMarksFromText(!ScCore->usingGUI()))
+//					return;
 				currItem->deleteSelectedTextFromFrame();
+			}
 
 			/*if (currItem->CPos < 0)
 				currItem->CPos = 0;
@@ -5211,6 +5345,18 @@
 				textSerializer->parseMemory(xml, xml.length());
 
 				StoryText* story = textSerializer->result<StoryText>();
+
+				//avoid pasting notes marks into notes frames
+				if (currItem->isNoteFrame())
+				{
+					story->setDoc(doc);
+					for (int pos=story->length() -1; pos >= 0; --pos)
+					{
+						ScText* hl = story->item(pos);
+						if (hl->hasMark() && (hl->mark->isNoteType()))
+							story->removeChars(pos,1);
+					}
+				}
 				if (UndoManager::undoEnabled())
 				{
 					ScItemState<StoryText> *is = new ScItemState<StoryText>(Um::Paste);
@@ -5245,6 +5391,8 @@
 				styleManager->setDoc(doc);
 				propertiesPalette->unsetDoc();
 				propertiesPalette->setDoc(doc);
+				marksManager->setDoc(doc);
+				nsEditor->setDoc(doc);
 				symbolPalette->unsetDoc();
 				symbolPalette->setDoc(doc);
 
@@ -5339,6 +5487,8 @@
 				styleManager->setDoc(doc);
 				propertiesPalette->unsetDoc();
 				propertiesPalette->setDoc(doc);
+				marksManager->setDoc(doc);
+				nsEditor->setDoc(doc);
 				symbolPalette->unsetDoc();
 				symbolPalette->setDoc(doc);
 				inlinePalette->unsetDoc();
@@ -5381,6 +5531,8 @@
 			delete activeTransaction;
 			activeTransaction = NULL;
 		}
+		if (doc->notesChanged())
+			doc->notesFramesUpdate();
 		slotDocCh(false);
 	}
 }
@@ -5693,6 +5845,8 @@
 		doc->addPageToSection(wo, where, 1);
 	else
 		doc->addPageToSection(wo+1, where, 1);
+
+	doc->updateEndnotesFrames();
 	doc->changed();
 	updateGUIAfterPagesChanged();
 }
@@ -5819,6 +5973,7 @@
 	doc->changed();
 	doc->addPageToSection(wo, where, numPages);
 	doc->reformPages();
+	doc->updateEndnotesFrames();
 	updateGUIAfterPagesChanged();
 
 	undoManager->setUndoEnabled(true);
@@ -6643,13 +6798,17 @@
 //					view->requestMode(modeEditClip);
 //					return;
 //				}
+				//setTBvals before placing cursor has no effect
+				currItem->itemText.setCursorPosition(0);
 				setTBvals(currItem);
-				currItem->itemText.setCursorPosition(0);
 			}
 			scrActions["editPaste"]->setEnabled(false);
 			charPalette->setEnabled(true, currItem);
 			if (currItem!=NULL && currItem->asTextFrame())
+			{
 				enableTextActions(&scrActions, true, currItem->currentCharStyle().font().scName());
+				currItem->asTextFrame()->togleEditModeActions();
+			}
 			if (ScMimeData::clipboardHasScribusData())
 			{
 				bool textFrameEditMode = ((currItem != NULL) && (currItem->asTextFrame()));
@@ -6693,6 +6852,9 @@
 // 				currItem->update();
 			}
 		}
+		//disable text action which work only text frame in edit mode
+		if ((mode != modeEdit) || !currItem->isTextFrame())
+			enableTextActions(&scrActions, false);
 		int docSelectionCount=doc->m_Selection->count();
 		if (mode == modeDrawBezierLine)
 		{
@@ -6956,6 +7118,9 @@
 		for (int d = 0; d < doc->Items->count(); ++d)
 		{
 			ite = doc->Items->at(d);
+			//do not delete notes frames
+			if (ite->isAutoNoteFrame())
+				continue;
 			if (ite->OwnPage == a)
 			{
 				ite->setLocked(false);
@@ -7007,6 +7172,7 @@
 	view->reformPagesView();
 	undoManager->setUndoEnabled(true); // ugly hack continues
 	view->GotoPage(qMin(doc->Pages->count()-1, oldPg));
+	doc->updateEndnotesFrames();
 	updateGUIAfterPagesChanged();
 	doc->rebuildMasterNames();
 	pagePalette->rebuildMasters();
@@ -7034,6 +7200,7 @@
 			doc->movePage(from-1, to, wo-1, wie);
 			updateGUIAfterPagesChanged();
 		}
+		doc->updateEndnotesFrames();
 	}
 	delete dia;
 }
@@ -7051,6 +7218,7 @@
 		int wo = dia->getWherePage();
 		doc->copyPage(pageNumberToCopy, wo, whereToInsert, copyCount);
 		view->Deselect(true);
+		doc->updateEndnotesFrames();
 		updateGUIAfterPagesChanged();
 		slotDocCh();
 	}
@@ -7088,6 +7256,7 @@
 			if (dia->masterPage() != Nam)
 				Apply_MasterPage(dia->masterPage(), doc->currentPage()->pageNr());
 		}
+		doc->updateEndnotesFrames();
 		//CB: Moved to changePageMargins for #2338
 		//doc->currentPage()->marginPreset = dia->getMarginPreset();
 		//view->reformPages(dia->getMoveObjects());
@@ -7950,6 +8119,8 @@
 	inlinePalette->startup();
 	charPalette->startup();
 	styleManager->startup();
+	marksManager->startup();
+	nsEditor->startup();
 	symbolPalette->startup();
 
 	// init the toolbars
@@ -10364,6 +10535,16 @@
 	scrMenuMgr->setMenuEnabled("InsertQuote", enabled);
 	scrMenuMgr->setMenuEnabled("InsertSpace", enabled);
 	scrMenuMgr->setMenuEnabled("InsertLigature", enabled);
+	scrMenuMgr->setMenuEnabled("InsertMark", enabled);
+	if (!enabled)
+	{
+		scrActions["insertMarkVariableText"]->setEnabled(false);
+		scrActions["insertMarkAnchor"]->setEnabled(false);
+		scrActions["insertMarkItem"]->setEnabled(false);
+		scrActions["insertMark2Mark"]->setEnabled(false);
+		scrActions["insertMarkNote"]->setEnabled(false);
+		scrActions["editMark"]->setEnabled(false);
+	}
 }
 
 void ScribusMainWindow::updateGUIAfterPagesChanged()
@@ -10415,3 +10596,625 @@
 	scrActions["tableAdjustTableToFrame"]->setEnabled(table);
 }
 
+void ScribusMainWindow::insertMark(MarkType mType)
+{
+	if (!HaveDoc)
+		return;
+	if (doc->m_Selection->count() != 1)
+		return;
+	if  (doc->appMode != modeEdit)
+		return;
+	UndoTransaction* trans = NULL;
+	PageItem* currItem = doc->m_Selection->itemAt(0);
+	if (currItem->isTextFrame())
+	{
+		if (currItem->HasSel)
+		{
+			if (UndoManager::instance()->undoEnabled())
+				trans = new UndoTransaction(undoManager->beginTransaction(Um::Selection,Um::IDelete,Um::Delete,"",Um::IDelete));
+			//inserting mark replace some selected text
+			currItem->asTextFrame()->deleteSelectedTextFromFrame();
+		}
+		ScItemsState* is = NULL;
+		if (insertMarkDlg(currItem->asTextFrame(), mType, is))
+		{
+			Mark* mrk = currItem->itemText.item(currItem->itemText.cursorPosition() -1)->mark;
+			view->updatesOn(false);
+			currItem->invalidateLayout();
+			currItem->layout();
+			if (mType == MARKNoteMasterType)
+			{
+				doc->setNotesChanged(true);
+				if (mrk->getNotePtr()->isEndNote())
+					doc->flag_updateEndNotes = true;
+				doc->setCursor2MarkPos(mrk->getNotePtr()->noteMark());
+				nsEditor->setNotesStyle(mrk->getNotePtr()->notesStyle());
+			}
+			doc->changed();
+			if (is != NULL)
+				is->set("label", mrk->label);
+			view->updatesOn(true);
+			view->DrawNew();
+		}
+		if (trans)
+		{
+			trans->commit();
+			delete trans;
+			trans = NULL;
+		}
+	}
+}
+
+void ScribusMainWindow::slotEditMark()
+{
+	if (!HaveDoc)
+		return;
+	if (doc->m_Selection->count() != 1)
+		return;
+	if  (doc->appMode != modeEdit)
+		return;
+	PageItem * currItem = doc->m_Selection->itemAt(0);
+	if (currItem->itemText.cursorPosition() < currItem->itemText.length())
+	{
+		ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+		if (hl->hasMark())
+		{
+			if (editMarkDlg(hl->mark, currItem->asTextFrame()))
+			{
+				if (hl->mark->isType(MARKVariableTextType))
+					doc->flag_updateMarksLabels = true;
+				else
+					currItem->invalid = true;
+				//doc->updateMarks();
+				doc->changed();
+				doc->regionsChanged()->update(QRectF());
+				view->DrawNew();
+			}
+			if (hl->mark->isNoteType())
+				nsEditor->setNotesStyle(hl->mark->getNotePtr()->notesStyle());
+		}
+	}
+}
+
+void ScribusMainWindow::slotUpdateMarks()
+{
+	if (!HaveDoc)
+		return;
+	if (doc->marksList().isEmpty())
+		return;
+	if (doc->updateMarks(true))
+	{
+		doc->changed();
+		doc->regionsChanged()->update(QRectF());
+	}
+}
+
+void ScribusMainWindow::slotInsertMarkNote()
+{
+	if (doc->m_docNotesStylesList.count() == 1)
+	{ //fast insert note with the only default notes style avaiable
+		PageItem* currItem = doc->m_Selection->itemAt(0);
+		Q_ASSERT(currItem->isTextFrame() && !currItem->isNoteFrame());
+		UndoTransaction* trans = NULL;
+		if (currItem->HasSel)
+		{
+			if (UndoManager::instance()->undoEnabled())
+				trans = new UndoTransaction(undoManager->beginTransaction(Um::Selection,Um::IDelete,Um::Delete,"",Um::IDelete));
+			//inserting mark replace some selected text
+			currItem->asTextFrame()->deleteSelectedTextFromFrame();
+		}
+		NotesStyle* nStyle = doc->m_docNotesStylesList.at(0);
+		QString label = "NoteMark_" + nStyle->name();
+		if (nStyle->range() == NSRsection)
+			label += " in section " + doc->getSectionNameForPageIndex(currItem->OwnPage) + " page " + QString::number(currItem->OwnPage +1);
+		else if (nStyle->range() == NSRpage)
+			label += " on page " + QString::number(currItem->OwnPage +1);
+		else if (nStyle->range() == NSRstory)
+			label += " in " + currItem->firstInChain()->itemName();
+		else if (nStyle->range() == NSRframe)
+			label += " in frame" + currItem->itemName();
+		if (doc->getMarkDefinied(label + "_1", MARKNoteMasterType) != NULL)
+			getUniqueName(label,doc->marksLabelsList(MARKNoteMasterType), "_"); //FIX ME here user should be warned that inserted mark`s label was changed
+		else
+			label = label + "_1";
+		Mark* mrk = doc->newMark();
+		mrk->label = label;
+		mrk->setType(MARKNoteMasterType);
+		mrk->setNotePtr(doc->newNote(nStyle));
+		mrk->getNotePtr()->setMasterMark(mrk);
+		mrk->setString("");
+		mrk->OwnPage = currItem->OwnPage;
+		currItem->itemText.insertMark(mrk);
+		currItem->invalidateLayout();
+		currItem->layout();
+		if (mrk->getNotePtr()->isEndNote())
+			doc->flag_updateEndNotes = true;
+		doc->regionsChanged()->update(QRectF());
+		doc->changed();
+		doc->setCursor2MarkPos(mrk->getNotePtr()->noteMark());
+		if (UndoManager::undoEnabled())
+		{
+			ScItemsState* is = new ScItemsState(UndoManager::InsertNote);
+			is->set("ETEA", mrk->label);
+			is->set("MARK", QString("new"));
+			is->set("label", mrk->label);
+			is->set("type", (int) MARKNoteMasterType);
+			is->set("strtxt", QString(""));
+			is->set("nStyle", nStyle->name());
+			is->set("at", currItem->itemText.cursorPosition() -1);
+			is->insertItem("inItem", currItem);
+			undoManager->action(doc, is);
+		}
+		if (trans)
+		{
+			trans->commit();
+			delete trans;
+			trans = NULL;
+		}
+	}
+	else
+		insertMark(MARKNoteMasterType);
+}
+
+bool ScribusMainWindow::insertMarkDlg(PageItem_TextFrame* currItem, MarkType mrkType, ScItemsState* &is)
+{
+	if (doc->masterPageMode() && (mrkType != MARKVariableTextType))
+		//avoid inserting in master pages other marks than Variable Text
+		return false;
+	
+	MarkInsertDlg* insertMDialog = NULL;
+	switch (mrkType)
+	{
+	case MARKAnchorType:
+		insertMDialog = (MarkInsertDlg*) new MarkAnchorDlg(this);
+		break;
+	case MARKVariableTextType:
+			insertMDialog = (MarkInsertDlg*) new MarkVariableTextDlg(doc->marksList(), this);
+		break;
+	case MARK2ItemType:
+		insertMDialog = (MarkInsertDlg*) new Mark2ItemDlg(this);
+		break;
+	case MARK2MarkType:
+			insertMDialog = (MarkInsertDlg*) new Mark2MarkDlg(doc->marksList(), NULL, this);
+		break;
+	case MARKNoteMasterType:
+		insertMDialog = (MarkInsertDlg*) new MarkNoteDlg(doc->m_docNotesStylesList, this);
+		break;
+	case MARKIndexType:
+		break;
+	default:
+		break;
+	}
+	if (insertMDialog == NULL)
+	{
+		qDebug() << "Dialog not implemented for such marks type " << mrkType;
+		return false;
+	}
+	bool docWasChanged = false;
+	
+	insertMDialog->setWindowTitle(tr("Insert new ") + insertMDialog->windowTitle());
+	if (insertMDialog->exec())
+	{
+		Mark* mrk = NULL;
+		Mark oldMark;
+		MarkData d;
+		if (currItem != NULL)
+			d.itemName = currItem->itemName();
+		QString label = "", text = "";
+		NotesStyle* NStyle = NULL;
+		bool insertExistedMark = false;
+		switch (mrkType)
+		{
+		case MARKAnchorType:
+			//only gets label for new mark
+			insertMDialog->values(label);
+			if (label.isEmpty())
+				label = tr("Anchor mark");
+			d.itemPtr = currItem;
+			break;
+		case MARKVariableTextType:
+			mrk = insertMDialog->values(label, text);
+			if ((mrk == NULL) && (text.isEmpty()))
+				return false; //FIX ME here user should be warned that inserting of mark fails and why
+			if (label.isEmpty())
+				label = tr("Mark with <%1> variable text").arg(text);
+			d.strtxt = text;
+			break;
+		case MARK2ItemType:
+			insertMDialog->values(label, d.itemPtr);
+			if (d.itemPtr == NULL)
+				return false; //FIX ME here user should be warned that inserting of mark fails and why
+			if (label.isEmpty())
+				label = tr("Mark to %1 item").arg(d.itemPtr->itemName());
+			d.strtxt = QString::number(d.itemPtr->OwnPage +1);
+			break;
+		case MARK2MarkType:
+			//gets pointer to referenced mark
+			Mark* mrkPtr;
+			insertMDialog->values(label, mrkPtr);
+			if (mrkPtr == NULL)
+				return false; //FIX ME here user should be warned that inserting of mark fails and why
+			if (label.isEmpty())
+				label = tr("Mark to %1 mark").arg(mrkPtr->label);
+			d.strtxt = QString::number(mrkPtr->OwnPage +1);
+			d.destmarkName = mrkPtr->label;
+			d.destmarkType = mrkPtr->getType();
+			break;
+		case MARKNoteMasterType:
+			//gets pointer to choosed notes style
+			NStyle = insertMDialog->values();
+			if (NStyle == NULL)
+				return false;
+
+			d.notePtr = doc->newNote(NStyle);
+			label = "NoteMark_" + NStyle->name();
+			if (NStyle->range() == NSRsection)
+				label += " in section " + doc->getSectionNameForPageIndex(currItem->OwnPage) + " page " + QString::number(currItem->OwnPage +1);
+			else if (NStyle->range() == NSRpage)
+				label += " on page " + QString::number(currItem->OwnPage +1);
+			else if (NStyle->range() == NSRstory)
+				label += " in " + currItem->firstInChain()->itemName();
+			else if (NStyle->range() == NSRframe)
+				label += " in frame" + currItem->itemName();
+			break;
+		case MARKIndexType:
+				return false;
+			break;
+		default:
+				return false;
+			break;
+		}
+		if (mrk == NULL)
+		{
+			//check if label for new mark can be used as is
+			if (mrkType == MARKNoteMasterType)
+			{
+				if (doc->getMarkDefinied(label + "_1", mrkType) != NULL)
+					getUniqueName(label,doc->marksLabelsList(mrkType), "_"); //FIX ME here user should be warned that inserted mark`s label was changed
+				else
+					label = label + "_1";
+			}
+			else
+				getUniqueName(label,doc->marksLabelsList(mrkType), "_");
+			mrk = doc->newMark();
+			mrk->setValues(label, currItem->OwnPage, mrkType, d);
+		}
+		else
+		{ // that must be variable text mark
+			oldMark = *mrk;
+			mrk->setString(d.strtxt);
+			mrk->label = label;
+			insertExistedMark = true;
+			doc->flag_updateMarksLabels = true;
+		}
+
+		currItem->itemText.insertMark(mrk);
+		mrk->OwnPage = currItem->OwnPage;
+
+
+		if (mrkType == MARKNoteMasterType)
+		{
+			mrk->getNotePtr()->setMasterMark(mrk);
+			mrk->setString("");
+		}
+
+		if (UndoManager::undoEnabled())
+		{
+			if (mrk->isType(MARKNoteMasterType))
+				is = new ScItemsState(UndoManager::InsertNote);
+			else if (insertExistedMark && ((oldMark.label != mrk->label) || (oldMark.getString() != mrk->getString())))
+				is = new ScItemsState(UndoManager::EditMark);
+			else
+				is = new ScItemsState(UndoManager::InsertMark);
+			is->set("ETEA", mrk->label);
+			is->set("label", mrk->label);
+			is->set("type", (int) mrk->getType());
+			if (insertExistedMark)
+			{
+				is->set("MARK", QString("insert_existing"));
+				if (mrk->label != oldMark.label)
+				{
+					is->set("labelOLD", oldMark.label);
+					is->set("labelNEW", mrk->label);
+					doc->flag_updateMarksLabels = true;
+				}
+				if (oldMark.getString() != mrk->getString())
+				{
+					is->set("strOLD", oldMark.getString());
+					is->set("strNEW", mrk->getString());
+				}
+			}
+			else
+			{
+				is->set("MARK", QString("new"));
+				is->set("strtxt", mrk->getString());
+				if (mrk->isType(MARK2MarkType))
+				{
+					QString dName;
+					MarkType dType;
+					mrk->getMark(dName, dType);
+					is->set("dName", dName);
+					is->set("dType", (int) dType);
+				}
+				if (mrk->isType(MARK2ItemType))
+					is->insertItem("itemPtr", mrk->getItemPtr());
+				if (mrk->isType(MARKNoteMasterType))
+					is->set("nStyle", mrk->getNotePtr()->notesStyle()->name());
+			}
+			is->set("at", currItem->itemText.cursorPosition() -1);
+			if (currItem->isNoteFrame())
+				is->set("noteframeName", currItem->getUName());
+			else
+				is->insertItem("inItem", currItem);
+			undoManager->action(doc, is);
+			docWasChanged = true;
+		}
+	}
+	delete insertMDialog;
+	return docWasChanged;
+}
+
+bool ScribusMainWindow::editMarkDlg(Mark *mrk, PageItem_TextFrame* currItem)
+{
+	MarkInsertDlg* editMDialog = NULL;
+	switch (mrk->getType())
+	{
+		case MARKAnchorType:
+			editMDialog = (MarkInsertDlg*) new MarkAnchorDlg(this);
+			editMDialog->setValues(mrk->label);
+			break;
+		case MARKVariableTextType:
+			if (currItem == NULL)
+				//invoked from Marks Manager
+				editMDialog = (MarkInsertDlg*) new MarkVariableTextDlg(mrk, this);
+			else
+				//invoked from mark`s entry in text
+				editMDialog = (MarkInsertDlg*) new MarkVariableTextDlg(doc->marksList(), this);
+			editMDialog->setValues(mrk->label, mrk->getString());
+			break;
+		case MARK2ItemType:
+			editMDialog = (MarkInsertDlg*) new Mark2ItemDlg(this);
+			editMDialog->setValues(mrk->label, mrk->getItemPtr());
+			break;
+		case MARK2MarkType:
+			{
+			editMDialog = (MarkInsertDlg*) new Mark2MarkDlg(doc->marksList(), mrk, this);
+				QString l;
+				MarkType t;
+				mrk->getMark(l,t);
+				Mark* m = doc->getMarkDefinied(l,t);
+				editMDialog->setValues(mrk->label, m);
+			}
+			break;
+		case MARKNoteMasterType:
+			{
+				//invoking editing note mark from master text
+				//so we go to edit note
+				TextNote* note = mrk->getNotePtr();
+				if (note == NULL)
+				{
+					qFatal("ScribusMainWindow::editMarkDlg - found note master mark with null pointer to note");
+					return false;
+				}
+				Mark* noteMark = note->noteMark();
+				doc->setCursor2MarkPos(noteMark);
+			}
+			break;
+		case MARKNoteFrameType:
+			{
+				//invoking editing mark from note frame
+				//so we go to master text
+				TextNote* note = mrk->getNotePtr();
+				if (note == NULL)
+				{
+					qFatal("ScribusMainWindow::editMarkDlg - found note frame mark with null pointer to note");
+					return false;
+				}
+				Mark* masterMark = note->masterMark();
+				doc->setCursor2MarkPos(masterMark);
+			}
+		case MARKIndexType:
+			return false;
+			break;
+		default:
+			break;
+	}
+	if (editMDialog == NULL) return false;
+
+	bool docWasChanged = false;
+
+	editMDialog->setWindowTitle(tr("Edit ") + editMDialog->windowTitle());
+	if (editMDialog->exec())
+	{
+		Mark oldMark = *mrk;
+		Mark* Mrk = NULL;
+		MarkData d;
+		if (currItem != NULL)
+			d.itemName = currItem->itemName();
+		QString label = "", text = "";
+		QString oldStr = mrk->getString();
+		bool newMark = false;
+		bool replaceMark = false;
+		switch (mrk->getType())
+		{
+			case MARKAnchorType:
+				//only gets label for new mark
+				editMDialog->values(label);
+				if (label.isEmpty())
+					label = tr("Anchor mark");
+				if (mrk->label != label)
+				{
+					getUniqueName(label,doc->marksLabelsList(mrk->getType()), "_"); //FIX ME here user should be warned that inserted mark`s label was changed
+					mrk->label = label;
+				}
+				break;
+			case MARKVariableTextType:
+				Mrk = editMDialog->values(label, text);
+				if (text.isEmpty())
+					return false; //FIX ME here user should be warned that editing of mark fails and why
+				if (label.isEmpty())
+					label = tr("Mark with <%1> variable text").arg(text);
+				if (Mrk != NULL)
+				{
+					if (Mrk != mrk)
+					{
+						ScText* hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+						hl->mark = Mrk;
+						mrk = Mrk;
+						oldMark = *mrk;
+						replaceMark = true;
+					}
+					if (mrk->label != label)
+					{
+						getUniqueName(label,doc->marksLabelsList(mrk->getType()), "_"); //FIX ME here user should be warned that inserted mark`s label was changed
+						mrk->label = label;
+						emit UpdateRequest(reqMarksUpdate);
+					}
+					if (text != oldStr)
+					{
+						mrk->setString(text);
+						docWasChanged = true;
+					}
+				}
+				else
+				{
+					d.strtxt = text;
+					mrk = doc->newMark();
+					getUniqueName(label,doc->marksLabelsList(mrk->getType()), "_"); //FIX ME here user should be warned that inserted mark`s label was changed
+					mrk->setValues(label, currItem->OwnPage, MARKVariableTextType, d);
+					ScText* hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+					hl->mark = mrk;
+					docWasChanged = true;
+					newMark = true;
+				}
+				break;
+			case MARK2ItemType:
+				editMDialog->values(label, d.itemPtr);
+				if (d.itemPtr == NULL)
+					return false; //FIX ME here user should be warned that inserting of mark fails and why
+				if (label.isEmpty())
+					label = tr("Mark to %1 item").arg(d.itemPtr->itemName());
+				if (d.itemPtr != mrk->getItemPtr())
+				{
+					mrk->setItemPtr(d.itemPtr);
+					mrk->setString(QString("%1").arg(d.itemPtr->OwnPage +1));
+					docWasChanged = true;
+				}
+				if (mrk->label != label)
+				{
+					getUniqueName(label,doc->marksLabelsList(mrk->getType()), "_"); //FIX ME here user should be warned that inserted mark`s label was changed
+					mrk->label = label;
+				}
+				break;
+			case MARK2MarkType:
+				{
+					//gets pointer to referenced mark
+					Mark* mrkPtr = NULL;
+					editMDialog->values(label, mrkPtr);
+					if (mrkPtr == NULL)
+						return false; //FIX ME here user should be warned that inserting of mark fails and why
+					if (label.isEmpty())
+						label = tr("Mark to %1 mark").arg(mrkPtr->label);
+					QString destLabel = mrkPtr->label;
+					MarkType destType = mrkPtr->getType();
+					if (d.destmarkName != destLabel || d.destmarkType != destType)
+					{
+						mrk->setMark(mrkPtr);
+						mrk->setString(QString("%1").arg(mrkPtr->OwnPage +1));
+						docWasChanged = true;
+					}
+					if (mrk->label != label)
+					{
+						getUniqueName(label,doc->marksLabelsList(mrk->getType()), "_"); //FIX ME here user should be warned that inserted mark`s label was changed
+						mrk->label = label;
+					}
+				}
+				break;
+			case MARKNoteMasterType:
+				break;
+			case MARKIndexType:
+				break;
+			default:
+				break;
+		}
+		if (UndoManager::undoEnabled())
+		{
+			ScItemsState* is = NULL;
+			if (newMark || replaceMark)
+				is = new ScItemsState(UndoManager::InsertMark);
+			else
+				is = new ScItemsState(UndoManager::EditMark);
+			is->set("ETEA", mrk->label);
+			if (currItem != NULL)
+			{
+				is->set("at", currItem->itemText.cursorPosition()-1);
+				if (currItem->isNoteFrame())
+					is->set("noteframeName", currItem->getUName());
+				else
+					is->insertItem("inItem", currItem);
+			}
+			is->set("label", mrk->label);
+			is->set("type", (int) mrk->getType());
+			is->set("strtxt", mrk->getString());
+			if (newMark)
+			{
+				is->set("MARK", QString("new"));
+				if (mrk->isType(MARK2MarkType))
+				{
+					QString dName;
+					MarkType dType;
+					mrk->getMark(dName, dType);
+					is->set("dName", dName);
+					is->set("dType", (int) dType);
+				}
+				if (mrk->isType(MARK2ItemType))
+					is->insertItem("itemPtr", mrk->getItemPtr());
+				if (mrk->isType(MARKNoteMasterType))
+					is->set("nStyle", mrk->getNotePtr()->notesStyle()->name());
+				doc->flag_updateMarksLabels = true;
+			}
+			else
+			{
+				if (replaceMark)
+					is->set("MARK", QString("replace"));
+				else
+					is->set("MARK", QString("edit"));
+				if (mrk->label != oldMark.label)
+				{
+					is->set("labelOLD", oldMark.label);
+					is->set("labelNEW", mrk->label);
+					doc->flag_updateMarksLabels = true;
+				}
+				if (mrk->getString() != oldMark.getString())
+				{
+					is->set("strtxtOLD", oldMark.getString());
+					is->set("strtxtNEW", mrk->getString());
+				}
+				if (mrk->isType(MARK2MarkType))
+				{
+					QString dNameOLD;
+					MarkType dTypeOLD;
+					oldMark.getMark(dNameOLD, dTypeOLD);
+					QString dName;
+					MarkType dType;
+					mrk->getMark(dName, dType);
+					if (dName != dNameOLD || dType != dTypeOLD)
+					{
+						is->set("dNameOLD", dNameOLD);
+						is->set("dTypeOLD", (int) dTypeOLD);
+						is->set("dNameNEW", dName);
+						is->set("dTypeNEW", (int) dType);
+					}
+				}
+				if (mrk->isType(MARK2ItemType) && mrk->getItemPtr() != oldMark.getItemPtr())
+				{
+					is->insertItem("itemPtrOLD", oldMark.getItemPtr());
+					is->insertItem("itemPtrNEW", mrk->getItemPtr());
+				}
+			}
+			undoManager->action(doc, is);
+		}
+	}
+	delete editMDialog;
+	return docWasChanged;
+}

Modified: trunk/Scribus/scribus/scribus.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/scribus.h
==============================================================================
--- trunk/Scribus/scribus/scribus.h (original)
+++ trunk/Scribus/scribus/scribus.h Sat Oct 27 15:56:36 2012
@@ -75,10 +75,12 @@
 class HelpBrowser;
 class InlinePalette;
 class LayerPalette;
+class MarksManager;
 class Measurements;
 class ScMWMenuManager;
 class ModeToolBar;
 class NodePalette;
+class NotesStylesEditor;
 class OutlinePalette;
 class PDFToolBar;
 class PSLib;
@@ -208,6 +210,8 @@
 	GuideManager *guidePalette;
 	CharSelect *charPalette;
 	PropertiesPalette *propertiesPalette;
+	MarksManager *marksManager;
+	NotesStylesEditor *nsEditor;
 	NodePalette *nodePalette;
 	OutlinePalette *outlinePalette;
 	Biblio *scrapbookPalette;
@@ -518,6 +522,19 @@
 	 * canvas modes/gestures.
 	 */
 	void updateTableMenuActions();
+	void emitUpdateRequest(int updateFlags) { emit UpdateRequest(updateFlags); }
+
+	//inserting marks
+	void slotInsertMark2Mark() { insertMark(MARK2MarkType); }
+	void slotInsertMarkAnchor() { insertMark(MARKAnchorType); }
+	void slotInsertMarkVariableText() { insertMark(MARKVariableTextType); }
+	void slotInsertMarkItem() { insertMark(MARK2ItemType); }
+	void slotInsertMarkNote();
+	void slotInsertMarkIndex() { insertMark(MARKIndexType); }
+	void slotEditMark();
+	//connected to signal emited by actions when "Update Marks" menu item is triggered
+	void slotUpdateMarks();
+	bool editMarkDlg(Mark *mrk, PageItem_TextFrame* currItem = NULL);
 
 signals:
 	void AppModeChanged(int oldMode, int newMode);
@@ -611,6 +628,10 @@
 
 	QPointer<HelpBrowser> helpBrowser;
 	QString osgFilterString;
+
+	void insertMark(MarkType);
+	bool insertMarkDlg(PageItem_TextFrame* item, MarkType mT, ScItemsState* &is);
+	int m_marksCount; //remember marks count from last call
 };
 
 #endif

Modified: trunk/Scribus/scribus/scribusdoc.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/scribusdoc.cpp
==============================================================================
--- trunk/Scribus/scribus/scribusdoc.cpp (original)
+++ trunk/Scribus/scribus/scribusdoc.cpp Sat Oct 27 15:56:36 2012
@@ -53,6 +53,8 @@
 #include "hyphenator.h"
 #include "ui/inserttablecolumnsdialog.h"
 #include "ui/inserttablerowsdialog.h"
+#include "notesstyles.h"
+#include "ui/notesstyleseditor.h"
 #include "pageitem.h"
 #include "pageitem_imageframe.h"
 #include "pageitem_latexframe.h"
@@ -62,6 +64,7 @@
 #include "pageitem_polyline.h"
 #include "pageitem_table.h"
 #include "pageitem_textframe.h"
+#include "pageitem_noteframe.h"
 #ifdef HAVE_OSG
 	#include "pageitem_osgframe.h"
 #endif
@@ -103,6 +106,12 @@
 #include "colormgmt/sccolormgmtenginefactory.h"
 #include "ui/hruler.h"
 #include "ui/layers.h"
+#include "ui/MarkInsertDlg.h"
+#include "ui/mark2item.h"
+#include "ui/mark2mark.h"
+#include "ui/markanchor.h"
+#include "ui/markvariabletext.h"
+#include "ui/marksmanager.h"
 #include "ui/scmessagebox.h"
 #include "ui/storyeditor.h"
 
@@ -261,7 +270,12 @@
 	m_alignTransaction(NULL),
 	m_currentPage(NULL),
 	m_updateManager(),
-	m_docUpdater(NULL)
+	m_docUpdater(NULL),
+	flag_notesChanged(false),
+	flag_restartMarksRenumbering(false),
+	flag_updateMarksLabels(false),
+	flag_updateEndNotes(false),
+	flag_layoutNotesFrames(true)
 {
 	docUnitRatio=unitGetRatioFromIndex(docPrefsData.docSetupPrefs.docUnitIndex);
 	docPrefsData.docSetupPrefs.pageHeight=0;
@@ -357,7 +371,12 @@
 	m_alignTransaction(NULL),
 	m_currentPage(NULL),
 	m_updateManager(),
-	m_docUpdater(NULL)
+	m_docUpdater(NULL),
+	flag_notesChanged(false),
+	flag_restartMarksRenumbering(false),
+	flag_updateMarksLabels(false),
+	flag_updateEndNotes(false),
+	flag_layoutNotesFrames(true)
 {
 	docPrefsData.docSetupPrefs.docUnitIndex=unitindex;
 	docPrefsData.docSetupPrefs.pageHeight=pagesize.height();
@@ -550,6 +569,9 @@
 	m_masterPageMode=true; // quick hack to force the change of pointers in setMasterPageMode();
 	setMasterPageMode(false);
 	addSymbols();
+	//for loading old documents where default notes style is not saved
+	if (m_docNotesStylesList.isEmpty())
+		m_docNotesStylesList.append(new NotesStyle());
 }
 
 
@@ -651,6 +673,13 @@
 			delete pa.items.takeFirst();
 		}
 	}
+	//deleting resources alocated for marks and notes
+	while (! m_docNotesList.isEmpty())
+		delete m_docNotesList.takeFirst();
+	while (!m_docMarksList.isEmpty())
+		delete m_docMarksList.takeFirst();
+	while (! m_docNotesStylesList.isEmpty())
+		delete m_docNotesStylesList.takeFirst();
 	docPatterns.clear();
 	docGradients.clear();
 	while (!DocItems.isEmpty())
@@ -1256,6 +1285,15 @@
 			itemlist = NULL;
 	}
 #endif
+	foreach (NotesStyle* nStyle, m_docNotesStylesList)
+	{ //update styles names in notes styles
+		if (nStyle == NULL)
+			continue;
+		if (newNames.styles().contains(nStyle->notesParStyle()))
+			nStyle->setNotesParStyle(newNames.styles().value(nStyle->notesParStyle()));
+		if (newNames.charStyles().contains(nStyle->marksChStyle()))
+			nStyle->setMarksCharStyle(newNames.charStyles().value(nStyle->marksChStyle()));
+	}
 	for (QHash<int, PageItem*>::iterator itf = FrameItems.begin(); itf != FrameItems.end(); ++itf)
 	{
 		PageItem *currItem = itf.value();
@@ -1798,6 +1836,412 @@
 						ss->getDouble("NEW_PAGE_INITIALHEIGHT"), ss->getDouble("NEW_PAGE_INITIALWIDTH"),
 						ss->getDouble("NEW_PAGE_HEIGHT"), ss->getDouble("NEW_PAGE_WIDTH"), ss->getInt("NEW_PAGE_ORIENTATION"),
 						ss->get("NEW_PAGE_SIZE"), ss->getInt("NEW_PAGE_MARGINPRESET"), ss->getBool("OLD_PAGE_MOVEOBJECTS"), ss->getInt("PAGE_NUM"), ss->getInt("NEW_PAGE_TYPE"));
+			}
+		}
+		else if (ss->contains("DELETE_FRAMETEXT"))
+		{
+			PageItem * nF = getItemFromName(ss->get("noteframeName"));
+			Q_ASSERT(nF != NULL);
+			nF->asNoteFrame()->restoreDeleteNoteText(ss, isUndo);
+		}
+		else if (ss->contains("INSERT_FRAMETEXT"))
+		{
+			PageItem * nF = getItemFromName(ss->get("noteframeName"));
+			Q_ASSERT(nF != NULL);
+			nF->asNoteFrame()->restoreInsertNoteText(ss,isUndo);
+		}
+		else if (ss->contains("NSTYLE"))
+		{
+			NotesStyle* NS = NULL;
+			if ((ss->get("NSTYLE") == "new" && isUndo) || (ss->get("NSTYLE") == "delete" && !isUndo))
+				deleteNotesStyle(ss->get("name"));
+			else if ((ss->get("NSTYLE") == "new" && !isUndo) || (ss->get("NSTYLE") == "delete" && isUndo))
+			{
+				NS = new NotesStyle();
+				NS->setName(ss->get("name"));
+				NS->setStart(ss->getInt("start"));
+				NS->setEndNotes(ss->getBool("endNotes"));
+				NS->setType((NumerationType) ss->getInt("numStyle"));
+				NS->setRange((NumerationRange) ss->getInt("range"));
+				NS->setPrefix(ss->get("prefix"));
+				NS->setSuffix(ss->get("suffix"));
+				NS->setAutoNotesHeight(ss->getBool("autoH"));
+				NS->setAutoNotesWidth(ss->getBool("autoW"));
+				NS->setAutoWeldNotesFrames(ss->getBool("autoWeld"));
+				NS->setAutoRemoveEmptyNotesFrames(ss->getBool("autoRemove"));
+				NS->setSuperscriptInMaster(ss->getBool("superMaster"));
+				NS->setSuperscriptInNote(ss->getBool("superNote"));
+				NS->setMarksCharStyle(ss->get("marksChStyle"));
+				NS->setNotesParStyle(ss->get("notesParStyle"));
+				m_docNotesStylesList.append(NS);
+				scMW()->emitUpdateRequest(reqMarksUpdate);
+			}
+			else if (ss->get("NSTYLE") == "edit")
+			{
+				if (isUndo)
+					NS = getNotesStyle(ss->get("NEWname"));
+				else
+					NS = getNotesStyle(ss->get("name"));
+				Q_ASSERT(NS != NULL);
+				//check if Notes Style change form footnotes to endnotes or range of numeration was changed
+				//if use delete all notes frames with current style
+				bool delNF = false;
+				if (ss->getBool("NEWendNotes") != ss->getBool("endNotes")
+					|| ((isUndo && (ss->getBool("endNotes") && (NumerationRange) ss->getInt("range") != (NumerationRange) ss->getInt("NEWrange")))
+					|| (!isUndo && (ss->getBool("NEWendNotes") && ((NumerationRange) ss->getInt("NEWrange") != (NumerationRange) ss->getInt("range"))))))
+						delNF = true;
+				if (delNF)
+				{
+					foreach (PageItem_NoteFrame* nF, listNotesFrames(NS))
+						delNoteFrame(nF, false);
+					flag_updateEndNotes = NS->isEndNotes();
+				}
+				if (isUndo)
+				{
+					NS->setName(ss->get("name"));
+					NS->setStart(ss->getInt("start"));
+					NS->setRange((NumerationRange) ss->getInt("range"));
+					NS->setEndNotes(ss->getBool("endNotes"));
+					NS->setType((NumerationType) ss->getInt("numStyle"));
+					NS->setPrefix(ss->get("prefix"));
+					NS->setSuffix(ss->get("suffix"));
+					NS->setAutoNotesHeight(ss->getBool("autoH"));
+					NS->setAutoNotesWidth(ss->getBool("autoW"));
+					NS->setAutoWeldNotesFrames(ss->getBool("autoWeld"));
+					NS->setAutoRemoveEmptyNotesFrames(ss->getBool("autoRemove"));
+					NS->setSuperscriptInMaster(ss->getBool("superMaster"));
+					NS->setSuperscriptInNote(ss->getBool("superNote"));
+					NS->setMarksCharStyle(ss->get("marksChStyle"));
+					NS->setNotesParStyle(ss->get("notesParStyle"));
+				}
+				else
+				{
+					NS->setName(ss->get("NEWname"));
+					NS->setStart(ss->getInt("NEWstart"));
+					NS->setRange((NumerationRange) ss->getInt("NEWrange"));
+					NS->setEndNotes(ss->getBool("NEWendNotes"));
+					NS->setType((NumerationType) ss->getInt("NEWnumStyle"));
+					NS->setPrefix(ss->get("NEWprefix"));
+					NS->setSuffix(ss->get("NEWsuffix"));
+					NS->setAutoNotesHeight(ss->getBool("NEWautoH"));
+					NS->setAutoNotesWidth(ss->getBool("NEWautoW"));
+					NS->setAutoWeldNotesFrames(ss->getBool("NEWautoWeld"));
+					NS->setAutoRemoveEmptyNotesFrames(ss->getBool("NEWautoRemove"));
+					NS->setSuperscriptInMaster(ss->getBool("NEWsuperMaster"));
+					NS->setSuperscriptInNote(ss->getBool("NEWsuperNote"));
+					NS->setMarksCharStyle(ss->get("NEWmarksChStyle"));
+					NS->setNotesParStyle(ss->get("NEWnotesParStyle"));
+				}
+				setNotesChanged(true);
+				if ((ss->get("marksChStyle") != ss->get("NEWmarksChStyle"))
+					|| (ss->getBool("superMaster") != ss->getBool("NEWsuperMaster")))
+					invalidateMasterFrames(NS);
+				updateNotesNums(NS);
+				updateNotesFramesSettings(NS);
+				if (flag_updateEndNotes)
+					updateEndnotesFrames(NS, true);
+				updateNotesFramesStyles(NS);
+				if (notesChanged())
+				{
+					flag_updateMarksLabels = true;
+					changed();
+					regionsChanged()->update(QRectF());
+				}
+			}
+			if (NS != NULL)
+				scMW()->nsEditor->setNotesStyle(NS);
+			else
+				scMW()->nsEditor->updateNSList();
+		}
+		else if (ss->contains("DELETE_NOTE"))
+		{
+			ScItemsState *is = dynamic_cast<ScItemsState*>(state);
+			if (is)
+			{
+				NotesStyle* nStyle = getNotesStyle(is->get("nStyle"));
+				PageItem* master = NULL;
+				if (is->contains("noteframeName"))
+					master = getItemFromName(is->get("noteframeName"));
+				else
+					master = (PageItem*) is->getItem("inItem");
+				if (isUndo)
+				{
+					TextNote* note = newNote(nStyle);
+					Mark* mrk = newMark();
+					mrk->setType(MARKNoteMasterType);
+					mrk->setNotePtr(note);
+					note->setMasterMark(mrk);
+					note->setSaxedText(is->get("noteTXT"));
+					master->itemText.insertMark(mrk, is->getInt("at"));
+					master->invalid = true;
+					if (!nStyle->isAutoRemoveEmptyNotesFrames())
+					{
+						PageItem_NoteFrame* nF = (PageItem_NoteFrame*) is->getItem("noteframe");
+						Q_ASSERT(nF != NULL);
+						master->asTextFrame()->setNoteFrame(nF);
+					}
+					setNotesChanged(true);
+					if (note->isEndNote())
+						flag_updateEndNotes = true;
+				}
+				else
+				{
+					TextNote* note = master->itemText.item(is->getInt("at"))->mark->getNotePtr();
+					if (note->isEndNote())
+						flag_updateEndNotes = true;
+					deleteNote(note);
+				}
+				master->invalidateLayout();
+				master->updateLayout();
+			}
+		}
+		else if (ss->contains("MARK"))
+		{
+			ScItemsState *is = dynamic_cast<ScItemsState*>(state);
+			if (is)
+			{
+				Mark* mrk = getMarkDefinied(is->get("label"), (MarkType) is->getInt("type"));
+				if (mrk == NULL && is->contains("labelOLD"))
+					mrk = getMarkDefinied(is->get("labelOLD"), (MarkType) is->getInt("type"));
+				int pos = is->getInt("at");
+				bool isAutoNoteFrame = false;
+				PageItem* currItem = NULL;
+				if (is->contains("noteframeName"))
+				{
+					currItem = getItemFromName(is->get("noteframeName"));
+					if (currItem != NULL)
+						isAutoNoteFrame = currItem->asNoteFrame()->isAutoFrame();
+				}
+				else
+					currItem = (PageItem*) is->getItem("inItem");
+				if (isUndo)
+				{
+					if (is->get("MARK") == "new")
+					{
+						Q_ASSERT(mrk != NULL);
+						if (mrk->isNoteType())
+						{
+							TextNote* note = mrk->getNotePtr();
+							NotesStyle* nStyle = note->notesStyle();
+							if (note->isEndNote())
+								flag_updateEndNotes = true;
+							deleteNote(note);
+							updateNotesNums(nStyle);
+						}
+						else
+							eraseMark(mrk, true, currItem, true);
+					}
+					else if (is->get("MARK") == "replace")
+					{
+						Q_ASSERT(pos >= 0);
+						Q_ASSERT(currItem != NULL);
+						Q_ASSERT(mrk != NULL);
+						Mark* mrk = getMarkDefinied(is->get("label"), (MarkType) is->getInt("type"));
+						currItem->itemText.item(pos)->mark = mrk;
+						if (is->contains("strtxtOLD"))
+						{
+							mrk->setString(is->get("strtxtOLD"));
+							invalidateVariableTextFrames(mrk, false);
+						}
+						if (is->contains("labelOLD"))
+							mrk->label = is->get("labelOLD");
+					}
+					else if (is->get("MARK") == "edit")
+					{
+						Q_ASSERT(mrk != NULL);
+						if (is->contains("labelOLD"))
+							mrk->label = is->get("labelOLD");
+						if (is->contains("strtxtOLD"))
+						{
+							mrk->setString(is->get("strtxtOLD"));
+							invalidateVariableTextFrames(mrk, false);
+						}
+						if (is->contains("dNameOLD"))
+							mrk->setMark(is->get("dNameOLD"), (MarkType) is->getInt("dTypeOLD"));
+						if (is->getItem("itemPtrOLD") != NULL)
+							mrk->setItemPtr((PageItem*) is->getItem("itemPtrOLD"));
+					}
+					else if (is->get("MARK") == "insert_existing")
+					{
+						Q_ASSERT(pos >= 0);
+						Q_ASSERT(currItem != NULL);
+						Q_ASSERT(mrk != NULL);
+						currItem->itemText.removeChars(pos,1);
+						if (is->contains("strOLD"))
+						{
+							mrk->setString(is->get("strOLD"));
+							invalidateVariableTextFrames(mrk, false);
+						}
+						if (is->contains("labelOLD"))
+							mrk->label = is->get("labelOLD");
+					}
+					else if (is->get("MARK") == "delete")
+					{
+						mrk = newMark();
+						mrk->label = is->get("label");
+						mrk->setType((MarkType) is->getInt("type"));
+						Q_ASSERT(pos >= 0);
+						Q_ASSERT(currItem != NULL);
+						currItem->itemText.insertMark(mrk, pos);
+						if (is->contains("strtxt"))
+						{
+							mrk->setString(is->get("strtxt"));
+							invalidateVariableTextFrames(mrk, false);
+						}
+						if (is->contains("dName"))
+							mrk->setMark(is->get("dName"), (MarkType) is->getInt("dType"));
+						if (is->getItem("itemPtr") != NULL)
+							mrk->setItemPtr((PageItem*) is->getItem("itemPtrOLD"));
+					}
+					else if (is->get("MARK") == "eraseFromText") ////for non-unique marks
+					{
+						Q_ASSERT(pos >= 0);
+						Q_ASSERT(mrk != NULL);
+						Q_ASSERT(currItem != NULL);
+						currItem->itemText.insertMark(mrk, pos);
+						if (is->contains("strNew"))
+						{
+							mrk->setString(is->get("strNEW"));
+							invalidateVariableTextFrames(mrk, false);
+						}
+					}
+					else if (is->get("MARK") == "delNonUnique")
+					{
+						//used if deleting non-unique marks by MarksManager
+						mrk = newMark();
+						mrk->label = is->get("label");
+						mrk->setType((MarkType) is->getInt("type"));
+						mrk->setString(is->get("strtxt"));
+						for (int i=0; i < is->insertItemPos.count(); ++i)
+						{
+							PageItem* item = (PageItem*) is->insertItemPos[i].first;
+							item->itemText.insertMark(mrk, is->insertItemPos[i].second);
+							item->invalid = true;
+						}
+					}
+					else
+					{
+						Q_ASSERT(false);
+						qDebug() << "MARK undo - unhandled " << is->get("MARK");
+					}
+				}
+				else  //REDO
+				{
+					if (is->get("MARK") == "new")
+					{
+						if (currItem == NULL)
+						{
+							qDebug() << "Wrong inItem in undo step for mark";
+							return;
+						}
+						mrk = newMark();
+						mrk->label = is->get("label");
+						mrk->setType((MarkType) is->getInt("type"));
+						Q_ASSERT(currItem != NULL);
+						Q_ASSERT(pos >= 0);
+						currItem->itemText.insertMark(mrk, pos);
+						if (is->contains("strtxt"))
+							mrk->setString(is->get("strtxt"));
+						if (is->contains("dName"))
+							mrk->setMark(is->get("dName"), (MarkType) is->getInt("dType"));
+						if (is->getItem("itemPtr") != NULL)
+							mrk->setItemPtr((PageItem*) is->getItem("itemPtrOLD"));
+						if (mrk->isType(MARKNoteMasterType))
+						{
+							NotesStyle* nStyle = getNotesStyle(is->get("nStyle"));;
+							TextNote* note = newNote(nStyle);
+							mrk->setNotePtr(note);
+							note->setMasterMark(mrk);
+							if (nStyle->isEndNotes())
+								flag_updateEndNotes = true;
+							updateNotesNums(nStyle);
+						}
+					}
+					else if (is->get("MARK") == "replace")
+					{
+						Q_ASSERT(currItem != NULL);
+						Q_ASSERT(pos >= 0);
+						currItem->itemText.item(pos)->mark = getMarkDefinied(is->get("label"), (MarkType) is->getInt("type"));
+						if (is->contains("strtxtNEW"))
+						{
+							mrk->setString(is->get("strtxtNEW"));
+							invalidateVariableTextFrames(mrk, false);
+						}
+						if (is->contains("labelNEW"))
+							mrk->label = is->get("labelNEW");
+					}
+					else if (is->get("MARK") == "edit")
+					{
+						if (is->contains("labelNEW"))
+							mrk->label = is->get("labelNEW");
+						if (is->contains("strtxtNEW"))
+						{
+							mrk->setString(is->get("strtxtNEW"));
+							invalidateVariableTextFrames(mrk, false);
+						}
+						if (is->contains("dNameNEW"))
+							mrk->setMark(is->get("dNameNEW"), (MarkType) is->getInt("dTypeNEW"));
+						if (is->getItem("itemPtrNEW") != NULL)
+							mrk->setItemPtr((PageItem*) is->getItem("itemPtrNEW"));
+					}
+					else if (is->get("MARK") == "insert_existing")
+					{
+						Q_ASSERT(currItem != NULL);
+						Q_ASSERT(pos >= 0);
+						currItem->itemText.insertMark(mrk, pos);
+						if (is->contains("strNew"))
+						{
+							mrk->setString(is->get("strNEW"));
+							invalidateVariableTextFrames(mrk, false);
+						}
+						if (is->contains("labelNEW"))
+							mrk->label = is->get("labelNEW");
+					}
+					else if (is->get("MARK") == "eraseFromText") //for non-unique marks
+					{
+						Q_ASSERT(currItem != NULL);
+						Q_ASSERT(pos >= 0);
+						currItem->itemText.removeChars(pos,1);
+					}
+					else if (is->get("MARK") == "delete")
+					{
+						if (!mrk->isUnique())
+						{
+							Q_ASSERT(currItem != NULL);
+							Q_ASSERT(pos >= 0);
+							currItem->itemText.removeChars(pos,1);
+						}
+						else
+						{
+							if (mrk->isType(MARKNoteMasterType))
+							{
+								TextNote* note = mrk->getNotePtr();
+								NotesStyle* nStyle = note->notesStyle();
+								if (note->isEndNote())
+									flag_updateEndNotes = true;
+								deleteNote(note);
+								updateNotesNums(nStyle);
+							}
+							else
+								eraseMark(mrk, true);
+						}
+					}
+					else if (is->get("MARK") == "delNonUnique")
+					{
+						//used if deleting non-unique marks by MarksManager
+						eraseMark(mrk, true, NULL, true);
+					}
+					else
+					{
+						qDebug() << "MARK redo - unhandled " << is->get("MARK");
+					}
+				}
+				scMW()->emitUpdateRequest(reqMarksUpdate);
+				if (currItem != NULL && !isAutoNoteFrame)
+				{
+					currItem->invalidateLayout();
+					currItem->updateLayout();
+				}
 			}
 		}
 		if (layersUndo)
@@ -2353,6 +2797,7 @@
 		m_View->reformPagesView();
 		m_ScMW->updateGUIAfterPagesChanged();
 	}
+	updateEndnotesFrames();
 	changed();
 }
 
@@ -2411,6 +2856,7 @@
 			FirstAuto = Items->at(z);
 		LastAuto = Items->at(z);
 		Items->at(z)->setRedrawBounding();
+		updateEndnotesFrames();
 		return z;
 	}
 	return -1;
@@ -3964,22 +4410,12 @@
 
 void ScribusDoc::checkItemForFonts(PageItem *it, QMap<QString, QMap<uint, FPointArray> > & Really, uint lc)
 {
+	if (!it->isTextFrame() && !it->isPathText())
+		return;
+
 	FPointArray gly;
 	QChar chstr;
 
-	if (!it->isTextFrame() && !it->isPathText())
-		return;
-
-	/* May be needed for fixing #10371 completely
-	if (it->isAnnotation())
-	{
-		int annotType  = it->annotation().Type();
-		bool mustEmbed = ((annotType >= 2) && (annotType <= 6) && (annotType != 4));
-		if (mustEmbed && (!Really.contains(it->itemText.defaultStyle().charStyle().font().replacementName())))
-		{
-			Really.insert(it->itemText.defaultStyle().charStyle().font().replacementName(), QMap<uint, FPointArray>());
-		}
-	}*/
 	int start = it->isTextFrame() ? it->firstInFrame() : 0;
 	int stop  = it->isTextFrame() ? it->lastInFrame() + 1 : it->itemText.length();
 	for (int e = start; e < stop; ++e)
@@ -4833,7 +5269,7 @@
 	return true;
 }
 
-int ScribusDoc::itemAdd(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, const double x, const double y, const double b, const double h, const double w, const QString& fill, const QString& outline, const bool itemFinalised)
+int ScribusDoc::itemAdd(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, const double x, const double y, const double b, const double h, const double w, const QString& fill, const QString& outline, const bool itemFinalised, const bool noteFrame)
 {
 	assert(itemFinalised); // av: caller must wrap transaction around this if wanted
 	UndoTransaction* activeTransaction = NULL;
@@ -4851,6 +5287,9 @@
 			Q_ASSERT(frameType==PageItem::Rectangle || frameType==PageItem::Unspecified);
 			break;
 		case PageItem::TextFrame:
+			if (noteFrame)
+				newItem = new PageItem_NoteFrame(this, x, y, b, h, w, CommonStrings::None, outline);
+			else
 			newItem = new PageItem_TextFrame(this, x, y, b, h, w, CommonStrings::None, outline);
 			Q_ASSERT(frameType==PageItem::Rectangle || frameType==PageItem::Unspecified);
 			break;
@@ -5858,7 +6297,6 @@
 		{
 			transactionConversion->cancel();
 			delete transactionConversion;
-			transactionConversion = NULL;
 		}
 		return NULL;
 	}
@@ -6425,6 +6863,17 @@
 	return retVal;
 }
 
+QString ScribusDoc::getSectionNameForPageIndex(const uint pageIndex) const
+{
+	DocumentSectionMap::ConstIterator it = docPrefsData.docSectionMap.begin();
+	for (; it != docPrefsData.docSectionMap.end(); ++it)
+	{
+		if (pageIndex >= it.value().fromindex && pageIndex <= it.value().toindex)
+			return it.value().name;
+	}
+	return QString();
+}
+
 
 const QString ScribusDoc::getSectionPageNumberForPageIndex(const uint pageIndex) const
 {
@@ -7535,7 +7984,7 @@
 	{
 		UndoTransaction* activeTransaction = NULL;
 		m_updateManager.setUpdatesDisabled();
-		if (selectedItemCount > 1 && UndoManager::undoEnabled())
+		if (UndoManager::undoEnabled() && selectedItemCount > 1)
 			activeTransaction = new UndoTransaction(undoManager->beginTransaction(Um::SelectionGroup,
 																				  Um::IGroup, Um::SetShade, QString("%1").arg(sha),
 																				  Um::IShade));
@@ -8462,6 +8911,11 @@
 		}
 		else
 		{
+			if (currItem->isNoteFrame())
+				setNotesChanged(true);
+			else if (currItem->isTextFrame())
+				updateItemNotesFramesStyles(currItem, newStyle);
+			else 
 			currItem->itemText.setDefaultStyle(newStyle);
 		}
 		if (currItem->asPathText())
@@ -8536,6 +8990,13 @@
 		else
 		{
 			ParagraphStyle newStyle;
+			//for notes frames apply style from master frame
+			if (currItem->isNoteFrame() && (currItem->asNoteFrame()->masterFrame() != NULL))
+			{
+				newStyle.setParent(currItem->asNoteFrame()->masterFrame()->itemText.defaultStyle().parent());
+				newStyle.applyStyle(currItem->asNoteFrame()->masterFrame()->currentStyle());
+			}
+			else
 			newStyle.setParent(currItem->itemText.defaultStyle().parent());
 			if (UndoManager::undoEnabled())
 			{
@@ -8545,10 +9006,18 @@
 				undoManager->action(currItem, is);
 			}
 			currItem->itemText.setDefaultStyle(newStyle);
+			if (currItem->isTextFrame() && !currItem->isNoteFrame())
+				updateItemNotesFramesStyles(currItem, newStyle);
+			else if (currItem->isNoteFrame())
+				setNotesChanged(true);
 		}
 		currItem->invalid = true;
 		if (currItem->asPathText())
 			currItem->updatePolyClip();
+		if (currItem->isNoteFrame())
+			currItem->asNoteFrame()->updateNotesText();
+		else if (currItem->isTextFrame() && currItem->asTextFrame()->hasNoteFrame(NULL, true))
+			setNotesChanged(true);
 	}
 	if (activeTransaction)
 	{
@@ -8586,6 +9055,10 @@
 				undoManager->action(currItem, is);
 			}
 			currItem->itemText.setDefaultStyle(dstyle);
+			if (currItem->isNoteFrame())
+				setNotesChanged(true);
+			else if (currItem->isTextFrame())
+				updateItemNotesFramesStyles(currItem, dstyle);
 		}
 		if (currItemTextCount > 0)
 		{
@@ -8626,6 +9099,10 @@
 		}
 		if (currItem->asPathText())
 			currItem->updatePolyClip();
+		if (currItem->isNoteFrame())
+			currItem->asNoteFrame()->updateNotesText();
+		else if (currItem->isTextFrame() && currItem->asTextFrame()->hasNoteFrame(NULL, true))
+			setNotesChanged(true);
 		currItem->invalidateLayout();
 	}
 	if (activeTransaction)
@@ -8749,9 +9226,15 @@
 //			if (currItem->asPathText())
 			currItem->itemText.applyCharStyle(0, currItem->itemText.length(), newStyle);
 			currItem->invalid = true;
+			if (currItem->isNoteFrame())
+				setNotesChanged(true);
+			else if (currItem->isTextFrame())
+				updateItemNotesFramesStyles(currItem, dstyle);
 		}
 		if (currItem->asPathText())
 			currItem->updatePolyClip();
+		if (currItem->isNoteFrame())
+			currItem->asNoteFrame()->updateNotesText();
 		currItem->invalidateLayout();
 	}
 	if (activeTransaction)
@@ -8831,9 +9314,15 @@
 			currItem->itemText.setDefaultStyle(dstyle);
 //			if (currItem->asPathText())
 			currItem->itemText.setCharStyle(0, currItem->itemText.length(), newStyle);
+			if (currItem->isNoteFrame())
+				setNotesChanged(true);
+			else if (currItem->isTextFrame())
+				updateItemNotesFramesStyles(currItem, dstyle);
 		}
 		if (currItem->asPathText())
 			currItem->updatePolyClip();
+		if (currItem->isNoteFrame())
+			currItem->asNoteFrame()->updateNotesText();
 		currItem->invalidateLayout();
 	}
 	if (activeTransaction)
@@ -8937,9 +9426,15 @@
 				undoManager->action(currItem, is);
 			}
 			currItem->itemText.setDefaultStyle(defStyle);
+			if (currItem->isNoteFrame())
+				setNotesChanged(true);
+			else if (currItem->isTextFrame())
+				updateItemNotesFramesStyles(currItem, defStyle);
 		}
 		if (currItem->asPathText())
 			currItem->updatePolyClip();
+		if (currItem->isNoteFrame())
+			currItem->asNoteFrame()->updateNotesText();
 		currItem->invalidateLayout();
 	}
 	if (activeTransaction)
@@ -10109,7 +10604,9 @@
 //			currItem->Frame = false;
 			currItem->ClipEdited = true;
 //			currItem->FrameType = 3;
+			undoManager->setUndoEnabled(false);
 			AdjustItemSize(currItem);
+			undoManager->setUndoEnabled(true);
 		}
 	}
 	else
@@ -10188,7 +10685,6 @@
 					state->setItem(l);
 					undoManager->action(currItem, state);
 				}
-
 				currItem->PoLine.translate(deltaX, deltaY);
 				currItem->PoLine.map(matrixPre);
 				currItem->PoLine.map(comulatedMatrix);
@@ -10202,7 +10698,9 @@
 //				currItem->Frame = false;
 				currItem->ClipEdited = true;
 //				currItem->FrameType = 3;
+				undoManager->setUndoEnabled(false);
 				AdjustItemSize(currItem);
+				undoManager->setUndoEnabled(true);
 				Elements.append(currItem);
 			}
 			comulatedMatrix *= matrix;
@@ -10215,7 +10713,7 @@
 		RotMode (rotBack);
 		useRaster = savedAlignGrid;
 		SnapGuides = savedAlignGuides;
-		SnapGuides = savedAlignElement;
+		SnapElement = savedAlignElement;
 		DoDrawing = true;
 		m_Selection->delaySignalsOff();
 		view()->updatesOn(true);
@@ -10795,7 +11293,7 @@
 	selectedItemCount = delItems.count();
 
 	UndoTransaction* activeTransaction = NULL;
-	if (UndoManager::undoEnabled())
+	if (UndoManager::undoEnabled()) //always create transaction or check if item is reference for any mark or contains any mark or is welded etc
 		activeTransaction = new UndoTransaction(undoManager->beginTransaction(Um::Group + "/" + Um::Selection, Um::IGroup,
 																			  Um::Delete, tooltip, Um::IDelete));
 
@@ -10804,8 +11302,43 @@
 		currItem = delItems.at(selectedItemCount - (de + 1));
 		if ((currItem->asImageFrame()) && ((ScCore->fileWatcher->files().contains(currItem->Pfile) != 0) && (currItem->PictureIsAvailable)))
 			ScCore->fileWatcher->removeFile(currItem->Pfile);
-		if (currItem->asTextFrame())
-			currItem->dropLinks();
+		//delete marks pointed to that item
+		for (int a=0; a < m_docMarksList.count(); a++)
+		{
+			Mark* m = m_docMarksList.at(a);
+			Q_ASSERT(m != NULL);
+			if (m->isType(MARK2ItemType) && (m->getItemPtr() == currItem))
+			{
+				setUndoDelMark(m);
+				eraseMark(m, true, NULL, true);
+			}
+		}
+		if (currItem->isNoteFrame())
+		{
+			if (currItem->itemText.length() >0)
+			{
+				currItem->itemText.selectAll();
+				currItem->asTextFrame()->deleteSelectedTextFromFrame();
+				if (currItem->asNoteFrame()->masterFrame())
+					currItem->asNoteFrame()->masterFrame()->invalid = true;
+			}
+			if (!UndoManager::undoEnabled() || forceDeletion || currItem->isAutoNoteFrame())
+			{
+				itemList->removeAll(currItem);
+				delNoteFrame(currItem->asNoteFrame(), false, false);
+				continue;
+			}
+		}
+		else
+		{
+			if (currItem->asTextFrame())
+			{
+				currItem->itemText.selectAll();
+				currItem->asTextFrame()->removeMarksFromText(true);
+				currItem->asTextFrame()->delAllNoteFrames(false);
+				currItem->dropLinks();
+			}
+		}
 		if (currItem->isWelded())
 			currItem->unWeld();
 		if (currItem->isBookmark)
@@ -10821,7 +11354,7 @@
 			undoManager->action(Pages->at(0), is, currItem->getUPixmap());
 		}
 		itemList->removeAll(currItem);
-//		if (forceDeletion || !UndoManager::undoEnabled())
+//		undoManager->action(Pages->at(0), is, currItem->getUPixmap());
 		if (forceDeletion)
 			delete currItem;
 	}
@@ -11255,14 +11788,17 @@
 		return;
 	m_updateManager.setUpdatesDisabled();
 	UndoTransaction* outerTransaction = NULL;
-	if (UndoManager::undoEnabled())
+	if (UndoManager::undoEnabled() && selectedItemCount > 1)
 		outerTransaction = new UndoTransaction(undoManager->beginTransaction());
 	QString tooltip = Um::ItemsInvolved + "\n";
 	if (selectedItemCount > Um::ItemsInvolvedLimit)
 		tooltip = Um::ItemsInvolved2 + "\n";
 	for (uint a = 0; a < selectedItemCount; ++a)
 	{
+		UndoTransaction* activeTransaction = NULL;
 		PageItem *currItem = itemSelection->itemAt(a);
+		if (UndoManager::undoEnabled())
+			activeTransaction = new UndoTransaction(undoManager->beginTransaction());
 		currItem->setImageXYScale(sx, sy);
 		currItem->setImageXYOffset(ox/sx, oy/sy);
 		if (currItem->imageClip.size() != 0)
@@ -11276,6 +11812,16 @@
 		}
 		if (selectedItemCount <= Um::ItemsInvolvedLimit)
 			tooltip += "\t" + currItem->getUName() + "\n";
+		if (activeTransaction)
+		{
+			activeTransaction->commit(Um::Selection,
+									  Um::IImageFrame,
+									  Um::ImageScale,
+									  tooltip,
+									  Um::IImageScaling);
+			delete activeTransaction;
+			activeTransaction = NULL;
+		}
 		currItem->update();
 	}
 	if (outerTransaction)
@@ -13252,7 +13798,6 @@
 	}
 }
 
-
 void ScribusDoc::SnapToGuides(PageItem *currItem)
 {
 	int pg = OnPage(currItem);
@@ -13557,6 +14102,7 @@
 			currItem->updateClip();
 //			currItem->updateGradientVectors();
 		}
+			
 		if (activeTransaction)
 		{
 			currItem->checkChanges();
@@ -15016,7 +15562,7 @@
 	if (nodeTransaction) // is there the old clip stored for the undo action
 	{
 		FPointArray newClip(Doc->nodeEdit.isContourLine ? currItem->ContourLine : currItem->PoLine);
-		if (*oldClip != newClip)
+		if (*oldClip != newClip && UndoManager::undoEnabled())
 		{
 			QString name = Doc->nodeEdit.isContourLine ? Um::EditContour : Um::EditShape;
 			ScItemState<QPair<FPointArray, FPointArray> > *state =
@@ -15054,7 +15600,7 @@
 	if (nodeTransaction) // is there the old clip stored for the undo action
 	{
 		FPointArray newClip(Doc->nodeEdit.isContourLine ? currItem->ContourLine : currItem->PoLine);
-		if (*oldClip != newClip)
+		if (*oldClip != newClip && UndoManager::undoEnabled())
 		{
 			QString name = Doc->nodeEdit.isContourLine ? Um::EditContour : Um::EditShape;
 			state = new ScItemState<QPair<FPointArray, FPointArray> >(name);
@@ -15765,17 +16311,13 @@
 		for (uint i = 0; i < selectedItemCount; ++i)
 		{
 			PageItem *currItem = itemSelection->itemAt(i);
-			if (currItem!=NULL)
-			{
-				if (currItem->asTextFrame() && (currItem->nextInChain() != NULL || currItem->prevInChain() != NULL))
+			if (currItem != NULL && currItem->asTextFrame() && (currItem->nextInChain() != NULL || currItem->prevInChain() != NULL))
 					currItem->unlinkWithText(cutText);
 			}
-		}
 		regionsChanged()->update(QRectF());
 		changed();
 		itemSelection->itemAt(0)->emitAllToGUI();
 	}
-
 }
 
 void ScribusDoc::itemSelection_UnlinkTextFrameWithTextCut( Selection *customSelection)
@@ -16014,3 +16556,1352 @@
 		autoSaveTimer->start(docPrefsData.docSetupPrefs.AutoSaveTime);
 	emit updateAutoSaveClock();
 }
+
+QStringList ScribusDoc::marksLabelsList(MarkType type)
+{
+	QStringList nameList;
+	for (int a=0; a < m_docMarksList.count(); ++a)
+	{
+		Mark* m = m_docMarksList.at(a);
+		if (m == NULL)
+			continue;
+		if ((m != NULL) && m->isType(type))
+			nameList.append(m->label);
+	}
+	return nameList;
+}
+
+Mark* ScribusDoc::getMarkDefinied(QString l, MarkType t)
+{
+	foreach (Mark* mrk, m_docMarksList)
+	{
+		if ((mrk != NULL) && (mrk->label == l) && mrk->isType(t))
+			return mrk;
+	}
+	return NULL;
+}
+
+Mark *ScribusDoc::newMark(Mark* mrk)
+{
+	Mark* newMrk = new Mark();
+	if (mrk != NULL)
+		*newMrk = *mrk;
+	m_docMarksList.append(newMrk);
+	return newMrk;
+}
+
+TextNote *ScribusDoc::newNote(NotesStyle* NS)
+{
+//	if (newNote == NULL)
+	TextNote* newNote = new TextNote(NS);
+	m_docNotesList.append(newNote);
+	setNotesChanged(true);
+	return newNote;
+}
+
+PageItem* ScribusDoc::findMarkItem(Mark* mrk, int &lastItem)
+{
+	PageItem* item = NULL;
+	for (int a = lastItem +1; a < DocItems.count(); ++a)
+	{
+		item = DocItems.at(a);
+		if ((item != NULL) && item->isTextFrame() && (item->itemText.length() > 0))
+		{
+			for (int i = item->firstInFrame(); i <= item->lastInFrame(); ++i)
+			{
+				ScText* hl = item->itemText.item(i);
+				if (hl->hasMark(mrk))
+				{
+					lastItem = a;
+					return item;
+				}
+			}
+		}
+	}
+	lastItem = 0;
+	return NULL;
+}
+
+int ScribusDoc::findMarkCPos(Mark* mrk, PageItem* &currItem, int Start)
+{
+	if (currItem == NULL)
+		currItem = findFirstMarkItem(mrk);
+	if (currItem == NULL)
+		return -1;
+	Q_ASSERT(currItem->isTextFrame());
+
+	if (Start < currItem->firstInFrame())
+		Start = currItem->firstInFrame();
+
+	for (int i = Start; i < currItem->itemText.length(); ++i)
+	{
+		ScText* hl = currItem->itemText.item(i);
+		if (hl->hasMark(mrk))
+			return i;
+	}
+	return -1;
+}
+
+bool ScribusDoc::isMarkUsed(Mark* mrk, bool visible)
+{
+	foreach (PageItem* currItem, DocItems)
+	{
+		if (currItem->isTextFrame() && (currItem->itemText.length() > 0))
+		{
+			if (!visible && currItem->prevInChain() != NULL)
+				//check in whole itemText only for first frames in chain
+				continue;
+			int i = 0;
+			int end = currItem->itemText.length();
+			if (visible)
+			{
+				//search only in visible text
+				i = currItem->firstInFrame();
+				end = currItem->lastInFrame() +1;
+			}
+			for (; i < end; ++i)
+			{
+				ScText* hl = currItem->itemText.item(i);
+				if (hl->hasMark(mrk))
+					return true;
+			}
+		}
+	}
+	return false;
+}
+
+void ScribusDoc::setCursor2MarkPos(Mark *mark)
+{
+	if (mark == NULL)
+		return;
+	PageItem* item = NULL;
+	if (mark->isType(MARKNoteFrameType) || mark->isType(MARKNoteMasterType))
+		item = mark->getItemPtr();
+	if (item == NULL)
+		item = getItemFromName(mark->getItemName());
+	if (item == NULL)
+		item = findFirstMarkItem(mark);
+	if (item == NULL)
+		return;
+
+	int CPos = findMarkCPos(mark, item);
+	if (CPos > -1)
+	{
+		scMW()->deselectAll();
+		scMW()->selectItemFromOutlines(item, true, CPos +1);
+	}
+}
+
+bool ScribusDoc::eraseMark(Mark *mrk, bool fromText, PageItem *item, bool force)
+{
+	bool found = false;
+	if (fromText)
+	{
+		if (item != NULL)
+		{
+			int MPos = findMarkCPos(mrk, item);
+			while (MPos > -1)
+			{
+				if (mrk->isType(MARKNoteFrameType) && MPos > 1 && item->itemText.text(MPos -1) == SpecialChars::PARSEP)
+					item->itemText.removeChars(MPos-1,2);
+				else
+					item->itemText.removeChars(MPos,1);
+				found = true;
+				MPos = findMarkCPos(mrk, item);
+			}
+		}
+		else
+		{
+			//find and delete all mark`s apperences in text
+			int MPos = -1;
+			int itemIndex = -1;
+			item = findMarkItem(mrk, itemIndex);
+			while (item != NULL)
+			{
+				MPos = findMarkCPos(mrk, item);
+				while (MPos > -1)
+				{
+					item->itemText.removeChars(MPos,1);
+					MPos = findMarkCPos(mrk, item);
+				}
+				found = true;
+				item->asTextFrame()->invalidateLayout(false);
+				item = findMarkItem(mrk, itemIndex);
+			}
+		}
+	}
+	//remove mark references
+	for (int a=0; a < m_docMarksList.count(); ++a)
+	{
+		Mark* m = m_docMarksList.at(a);
+		if (m == NULL)
+			continue;
+		if (m->isType(MARK2MarkType))
+		{
+			QString l;
+			MarkType t;
+			m->getMark(l, t);
+			if (mrk == getMarkDefinied(l, t))
+			{
+				setUndoDelMark(m);
+				eraseMark(m, true, NULL, true);
+			}
+		}
+	}
+	//erase mark from marksMap
+	if (mrk->isUnique() || force)
+	{
+		m_docMarksList.removeOne(mrk);
+		delete mrk;
+	}
+	return found;
+}
+
+void ScribusDoc::setUndoDelMark(Mark *mrk)
+{ //used by MarksManager
+	if (UndoManager::undoEnabled())
+	{
+		ScItemsState* ims = new ScItemsState(Um::DeleteMark,"",Um::IDelete);
+		if (mrk->isUnique())
+		{
+			ims->set("MARK", QString("delete"));
+			PageItem* master = findFirstMarkItem(mrk);
+			if (master->isNoteFrame())
+				ims->set("noteframeName", master->getUName());
+			else
+				ims->insertItem("inItem", master);
+			ims->set("at", findMarkCPos(mrk, master));
+			if (mrk->isType(MARK2MarkType))
+			{
+				QString dName;
+				MarkType dType;
+				mrk->getMark(dName, dType);
+				ims->set("dName", dName);
+				ims->set("dType", (int) dType);
+			}
+			if (mrk->isType(MARK2ItemType))
+				ims->insertItem("itemPtr", mrk->getItemPtr());
+		}
+		else
+		{
+			ims->set("MARK", QString("delNonUnique"));
+			int MPos = -1;
+			int itemIndex = -1;
+			//find all mark insertions
+			PageItem* item = findMarkItem(mrk, itemIndex);
+			while (item != NULL)
+			{
+				int num = 0; //shift of insertion position for undo
+				MPos = findMarkCPos(mrk, item);
+				while (MPos > -1)
+				{
+					ims->insertItemPos.append(QPair<void*, int>((void*) item, MPos - num)); //-num as while undo text will be shorter (without marks)
+					//++num;
+					MPos = findMarkCPos(mrk, item, MPos+1);
+				}
+				item = findMarkItem(mrk, itemIndex);
+			}
+		}
+		ims->set("ETEA", mrk->label);
+		ims->set("label", mrk->label);
+		ims->set("type", (int) mrk->getType());
+		ims->set("strtxt", mrk->getString());
+		undoManager->action(this, ims);
+	}
+}
+
+bool ScribusDoc::invalidateVariableTextFrames(Mark* mrk, bool forceUpdate)
+{
+	if (!mrk->isType(MARKVariableTextType))
+		return false;
+	int itemNo = -1;
+	bool found = false;
+	PageItem* mItem = findMarkItem(mrk, itemNo);
+	while (mItem != NULL)
+	{
+		found = true;
+		mItem->asTextFrame()->invalidateLayout(false);
+		if (forceUpdate)
+			mItem->layout();
+		mItem = findMarkItem(mrk, itemNo);
+	}
+	return found;
+}
+
+//update strings (page number) for marks pointed to anchors and items
+//and update marks list in Marka Manager
+bool ScribusDoc::updateMarks(bool updateNotesMarks)
+{
+	if (m_docMarksList.isEmpty())
+	{
+		if ((!notesList().isEmpty() || notesChanged()) && updateNotesMarks && !isLoading())
+			return notesFramesUpdate();
+		return false;
+	}
+	Q_ASSERT(m_docMarksList.removeAll(NULL) == 0);
+
+	bool docWasChanged = false;
+
+	if (!isLoading())
+	{
+		//run for variable text (invalidate frames with variable text)
+		foreach (Mark* mrk, m_docMarksList)
+		{
+			if (mrk->isType(MARKVariableTextType))
+			{
+				if (invalidateVariableTextFrames(mrk, false))
+					docWasChanged = true;
+			}
+			else if (mrk->isUnique())
+			{
+				PageItem* mItem = findFirstMarkItem(mrk);
+				mrk->OwnPage =(mItem != NULL) ? mItem->OwnPage : -1;
+				mrk->setItemName((mItem != NULL) ? mItem->itemName() : "");
+			}
+		}
+	}
+	
+	//update marks for foot/endnotes
+	if (updateNotesMarks)
+	{
+		//update notes numbers
+		for (int i=0; i < m_docNotesStylesList.count(); ++i)
+		{
+			NotesStyle* NS = m_docNotesStylesList.at(i);
+			//update nums
+			if (updateNotesNums(NS))
+			{
+				//refresh endnotes content
+				if (flag_updateEndNotes || isLoading())
+					updateEndnotesFrames(NS);
+				docWasChanged = true;
+			}
+			if (flag_updateEndNotes)
+				updateEndnotesFrames(NS);
+			updateNotesFramesStyles(NS);
+		}
+		docWasChanged = notesFramesUpdate();
+	}
+
+	//for all marks
+	foreach (Mark* mrk, m_docMarksList)
+	{
+		//set mark page number
+		PageItem* mItem = findFirstMarkItem(mrk);
+		if (mItem != NULL)
+			mrk->OwnPage = mItem->OwnPage;
+		else
+			mrk->OwnPage = -1;
+		if (mrk->isType(MARK2ItemType))
+		{
+			if (mrk->getItemPtr() != NULL)
+			{
+				int page = mrk->getItemPtr()->OwnPage +1;
+				if (mrk->getString().toInt() != page)
+				{
+					mrk->setString(QString("%1").arg(page));
+					if (mItem != NULL)
+					{
+						mItem->asTextFrame()->invalidateLayout(false);
+						docWasChanged = true;
+					}
+				}
+			}
+			else
+				mrk->setString("");
+		}
+		else if (mrk->isType(MARK2MarkType))
+		{
+			QString l;
+			MarkType t;
+			mrk->getMark(l,t);
+			Mark* destMark = getMarkDefinied(l,t);
+			if (destMark != NULL)
+			{
+				PageItem* dItem = findFirstMarkItem(destMark);
+				if (dItem == NULL)
+				{
+					destMark->OwnPage = -1;
+					mrk->setString("");
+					docWasChanged = true;
+				}
+				else
+				{
+					destMark->OwnPage = dItem->OwnPage;
+					int page = destMark->OwnPage +1;
+					if (mrk->getString().toInt() != page)
+					{
+						mrk->setString(QString("%1").arg(page));
+						if (mItem != NULL)
+						{
+							mItem->asTextFrame()->invalidateLayout(false);
+							docWasChanged = true;
+						}
+					}
+				}
+			}
+			else
+			{
+				mrk->setString("");
+				docWasChanged = true;
+			}
+		}
+	}
+	return docWasChanged;
+}
+
+NotesStyle* ScribusDoc::newNotesStyle(NotesStyle NS)
+{
+	QString nsName = NS.name();
+
+	//if doc is loading overwrite current set
+	NotesStyle* newNS = getNotesStyle(nsName);
+	if (isLoading() && (newNS != NULL))
+		*newNS = NS;
+	else
+	{
+		//add new notes style
+		if (!validateNSet(NS))
+			return NULL;
+		newNS = new NotesStyle();
+		*newNS = NS;
+		QStringList nsNames;
+		for (int a = 0; a< m_docNotesStylesList.count(); ++a)
+			nsNames.append(m_docNotesStylesList.at(a)->name());
+		getUniqueName(nsName, nsNames, "_");
+		newNS->setName(nsName);
+		m_docNotesStylesList.append(newNS);
+		if (undoManager->undoEnabled())
+		{
+			SimpleState* ss = new SimpleState(UndoManager::NewNotesStyle);
+			ss->set("NSTYLE", QString("new"));
+			undoSetNotesStyle(ss, newNS);
+			undoManager->action(this, ss);
+		}
+	}
+	return newNS;
+}
+
+void ScribusDoc::renameNotesStyle(NotesStyle* NS, QString newName)
+{
+	foreach (Mark* mrk, m_docMarksList)
+		mrk->label.replace("_" + NS->name()+ "_", "_" + newName + "_");
+	NS->setName(newName);
+}
+
+void ScribusDoc::deleteNotesStyle(QString nsName)
+{
+	NotesStyle* NS = getNotesStyle(nsName);
+	assert(NS != NULL);
+	//do not delete default notes style
+	if (NS == m_docNotesStylesList.at(0))
+		return;
+	UndoTransaction* activeTransaction = NULL;
+	if (UndoManager::instance()->undoEnabled())
+		activeTransaction = new UndoTransaction(undoManager->beginTransaction(Um::DeleteNotesStyle,Um::IDelete,Um::Delete,"",Um::IDelete));
+	QList<TextNote*> toDel;
+	//search for notes to deleting
+	foreach (TextNote* note, m_docNotesList)
+	{
+		if (note->notesStyle() == NS)
+			toDel.append(note);
+	}
+	//deleting notes
+	QList<PageItem*> master2Update;
+	if (!toDel.isEmpty())
+	{
+		while (!toDel.isEmpty())
+		{
+			TextNote* note = toDel.takeFirst();
+			master2Update.append(findFirstMarkItem(note->masterMark()));
+			setUndoDelNote(note);
+			deleteNote(note);
+		}
+		while (!master2Update.isEmpty())
+			master2Update.takeFirst()->layout();
+	}
+	if (activeTransaction)
+	{
+		//undo is enabled
+		SimpleState* ss = new SimpleState(UndoManager::DeleteNotesStyle);
+		ss->set("NSTYLE", QString("delete"));
+		undoSetNotesStyle(ss, NS);
+		undoManager->action(this, ss);
+		
+		activeTransaction->commit();
+		delete activeTransaction;
+		activeTransaction = NULL;
+	}
+	flag_updateMarksLabels = true;
+	if (NS->isEndNotes())
+		flag_updateEndNotes = true;
+	notesFramesUpdate();
+	m_docNotesStylesList.removeOne(NS);
+	scMW()->emitUpdateRequest(reqMarksUpdate);
+	delete NS;
+}
+
+void ScribusDoc::undoSetNotesStyle(SimpleState* ss, NotesStyle *NS)
+{
+		ss->set("name", NS->name());
+		ss->set("start", NS->start());
+		ss->set("endNotes", NS->isEndNotes());
+		ss->set("numStyle", (int) NS->getType());
+		ss->set("range", (int) NS->range());
+		ss->set("prefix", NS->prefix());
+		ss->set("suffix", NS->suffix());
+		ss->set("autoH", NS->isAutoNotesHeight());
+		ss->set("autoW", NS->isAutoNotesWidth());
+		ss->set("autoWeld", NS->isAutoWeldNotesFrames());
+		ss->set("autoRemove", NS->isAutoRemoveEmptyNotesFrames());
+		ss->set("superMaster", NS->isSuperscriptInMaster());
+		ss->set("superNote", NS->isSuperscriptInNote());
+		ss->set("marksChStyle", NS->marksChStyle());
+		ss->set("notesParStyle", NS->notesParStyle());
+}
+
+NotesStyle* ScribusDoc::getNotesStyle(QString nsName)
+{
+	for (int a=0; a < m_docNotesStylesList.count(); ++a)
+	{
+		if (m_docNotesStylesList.at(a)->name() == nsName)
+			return m_docNotesStylesList.at(a);
+	}
+	return NULL;
+}
+
+void ScribusDoc::deleteNote(TextNote* note)
+{
+	if (note == NULL)
+		return;
+	PageItem_NoteFrame* nF = NULL;
+	if (note->noteMark() != NULL)
+		if (note->noteMark()->getItemPtr() != NULL)
+			nF = note->noteMark()->getItemPtr()->asNoteFrame();
+	if (nF == NULL)
+		nF = findFirstMarkItem(note->noteMark())->asNoteFrame();
+	Q_ASSERT(nF != NULL);
+	nF->removeNote(note);
+	PageItem* master = note->masterMark()->getItemPtr();
+	nF->invalid = true;
+	master->invalid = true;
+	if (nF->notesList().isEmpty() && nF->isAutoNoteFrame())
+	{
+		nF->deleteIt = true;
+		master->asTextFrame()->removeNoteFrame(nF);
+	}
+//	else
+//		master->asTextFrame()->setNoteFrame(nF);
+	if (note->masterMark() != NULL)
+		eraseMark(note->masterMark(), true, master);
+	if (note->noteMark() != NULL)
+		eraseMark(note->noteMark(), true, nF);
+	m_docNotesList.removeOne(note);
+	setNotesChanged(true);
+	if (note->isEndNote())
+		flag_updateEndNotes = true;
+	delete note;
+}
+
+void ScribusDoc::setUndoDelNote(TextNote *note)
+{ //used by MarksManager
+	if (UndoManager::undoEnabled())
+	{
+		ScItemsState* ims = new ScItemsState(Um::DeleteNote,"",Um::IDelete);
+		ims->set("DELETE_NOTE", QString("delete_note"));
+		ims->set("ETEA", note->masterMark()->label);
+		PageItem* master = note->masterMark()->getItemPtr();
+		int pos = findMarkCPos(note->masterMark(), master);
+		Q_ASSERT(pos > -1);
+		Q_ASSERT(master);
+		ims->insertItem("inItem", master);
+		ims->set("at", pos);
+		ims->set("noteTXT", note->saxedText());
+		ims->set("nStyle", note->notesStyle()->name());
+		if (!note->notesStyle()->isAutoRemoveEmptyNotesFrames())
+			ims->insertItem("noteframe", note->noteMark()->getItemPtr());
+		undoManager->action(this, ims);
+	}
+}
+
+void ScribusDoc::updateItemNotesNums(PageItem_TextFrame* frame, NotesStyle* nStyle, int &num)
+{
+	//update marks strings in master text and in notes frame (only numbers!)
+	//check if notes schould be added or removed from notes frame
+	int noteNum = num;
+	ScText* hl;
+	int index = 0;
+	bool doUpdate = false;
+
+	for (int pos = frame->firstInFrame(); pos <= frame->lastInFrame(); ++pos)
+	{
+		hl = frame->itemText.item(pos);
+		if (hl->hasMark() && hl->mark->isType(MARKNoteMasterType))
+		{
+			if (hl->mark->getNotePtr() == NULL)
+				continue;
+			if (hl->mark->getNotePtr()->notesStyle() == nStyle)
+			{
+				QString numStr = nStyle->prefix() + nStyle->numString(noteNum) + nStyle->suffix();
+				QString mStr = hl->mark->getString();
+				QString label = hl->mark->label;
+				if ((mStr != numStr) || flag_updateMarksLabels || flag_updateEndNotes)
+				{
+					doUpdate = true;
+					hl->mark->setString(numStr);
+					label = "NoteMark_" + nStyle->name();
+					if (nStyle->range() != NSRdocument)
+					{
+						if (nStyle->range() == NSRsection)
+							label += " in section " + getSectionNameForPageIndex(frame->OwnPage) + " page " + QString::number(frame->OwnPage +1);
+						else if (nStyle->range() == NSRpage)
+							label += " on page " + QString::number(frame->OwnPage +1);
+						else if (nStyle->range() == NSRstory)
+							label += " in " + frame->firstInChain()->itemName();
+						else if (nStyle->range() == NSRframe)
+							label += " in frame " + frame->itemName();
+					}
+					label += "_" + QString::number(noteNum);
+					hl->mark->label = label;
+				}
+				TextNote* note = hl->mark->getNotePtr();
+				note->setNum(noteNum);
+				note->masterMark()->setItemPtr(frame);
+				if (note->noteMark() != NULL)
+				{
+					note->noteMark()->setString(numStr);
+					label = label.replace("NoteMark","NoteFrameMark");
+					note->noteMark()->label = label;
+				}
+				++index;
+				++noteNum;
+			}
+		}
+	}
+	PageItem_NoteFrame * nF;
+	if (nStyle->isEndNotes())
+		nF = endNoteFrame(nStyle);
+	else
+		nF = frame->itemNoteFrame(nStyle);
+
+	if (doUpdate)
+	{
+		frame->invalidateLayout(false);
+		if ((nF != NULL) && !nF->deleteIt)
+		{
+			if (nStyle->isEndNotes())
+				m_docEndNotesFramesChanged.append(nF);
+			else
+				nF->invalidateLayout(true);
+		}
+	}
+	num = noteNum;
+	if (!nStyle->isEndNotes() && (index == 0) && (nF != NULL) && nF->isAutoNoteFrame())
+		nF->deleteIt = true;
+}
+
+bool ScribusDoc::updateNotesNums(NotesStyle *nStyle)
+{
+	bool docWasChanged = false;
+	flag_restartMarksRenumbering = false;
+	flag_updateEndNotes = false;
+	PageItem_NoteFrame* endNF = NULL;
+	if (nStyle->isEndNotes() && nStyle->range() == NSRdocument)
+	{
+		endNF = endNoteFrame(nStyle);
+		if (endNF != NULL)
+			clearNotesInFrameList(endNF);
+	}
+	flag_layoutNotesFrames = false;  //do not layout notes frames while counting notes
+	int num, i;
+	int itemsCount = Items->count();
+	if ((nStyle->range() == NSRdocument) || ((nStyle->range() == NSRsection) && docPrefsData.docSectionMap.isEmpty()))
+	{
+		//FIX ME: how to change frames order on page? and what about reverse page order?
+		num = nStyle->start();
+		for (int page = 0; page < Pages->count(); ++page)
+		{
+			for (i = 0; i < itemsCount; ++i)
+			{
+				PageItem* currItem = Items->at(i);
+				if ((currItem->OwnPage == page) && currItem->isTextFrame() && !currItem->isNoteFrame() && (currItem->itemText.length() > 0))
+				{
+					if (!currItem->asTextFrame()->isValidChainFromBegin())
+					{
+						currItem->layout();
+						if (flag_restartMarksRenumbering)
+						{
+							//restart whole update as items was changed
+							if (endNF != NULL)
+								clearNotesInFrameList(endNF);
+							page = -1;
+							i = -1;
+							itemsCount = Items->count();
+							num = nStyle->start();
+							docWasChanged = true;
+							flag_restartMarksRenumbering = false;
+							break;
+						}
+					}
+					if (nStyle->isEndNotes() || currItem->asTextFrame()->hasNoteFrame(nStyle, false))
+						updateItemNotesNums(currItem->asTextFrame(), nStyle, num);
+					if (currItem->asTextFrame()->hasNoteFrame(nStyle, false) && currItem->asTextFrame()->itemNoteFrame(nStyle)->invalid)
+						docWasChanged = true;
+					if (currItem->invalid)
+					{
+						currItem->layout();
+						docWasChanged = true;
+					}
+				}
+			}
+		}
+		if ((num == nStyle->start()) && nStyle->isEndNotes())
+		{
+			PageItem_NoteFrame* nF = endNoteFrame(nStyle);
+			if (nF != NULL && nF->isAutoNoteFrame())
+				nF->deleteIt = true;
+		}
+	}
+	else if (nStyle->range() == NSRsection)
+	{
+		Q_ASSERT(!docPrefsData.docSectionMap.isEmpty());
+		foreach (DocumentSection section, docPrefsData.docSectionMap.values())
+		{
+			num = nStyle->start();
+			for (int page = section.fromindex; page <= (int) section.toindex ; ++page)
+			{
+				if (nStyle->isEndNotes())
+				{
+					endNF = endNoteFrame(nStyle, getSectionKeyForPageIndex(page));
+					if (endNF != NULL)
+						clearNotesInFrameList(endNF);
+				}
+				for (i = 0; i < itemsCount; ++i)
+				{
+					PageItem* currItem = Items->at(i);
+					if (currItem == NULL)
+						continue;
+					if ((currItem->OwnPage == page) && currItem->isTextFrame() && !currItem->isNoteFrame() && (currItem->itemText.length() > 0))
+					{
+						if (!currItem->asTextFrame()->isValidChainFromBegin())
+						{
+							currItem->layout();
+							if (flag_restartMarksRenumbering)
+							{
+								//restart whole update as items was changed
+								if (endNF != NULL)
+									clearNotesInFrameList(endNF);
+								page = section.fromindex -1;
+								i = -1;
+								itemsCount = Items->count();
+								num = nStyle->start();
+								docWasChanged = true;
+								flag_restartMarksRenumbering = false;
+								break;
+							}
+						}
+						if (nStyle->isEndNotes() || currItem->asTextFrame()->hasNoteFrame(nStyle, false))
+							updateItemNotesNums(currItem->asTextFrame(), nStyle, num);
+						if (currItem->asTextFrame()->hasNoteFrame(nStyle, false) && currItem->asTextFrame()->itemNoteFrame(nStyle)->invalid)
+							docWasChanged = true;
+						if (currItem->invalid)
+						{
+							currItem->layout();
+							docWasChanged = true;
+						}
+					}
+				}
+				if ((i != -1) && (num == nStyle->start()) && nStyle->isEndNotes())
+				{
+					PageItem_NoteFrame* nF = endNoteFrame(nStyle);
+					if (nF != NULL && nF->isAutoNoteFrame())
+						nF->deleteIt = true;
+				}
+			}
+		}
+	}
+	else if (nStyle->range() == NSRstory || nStyle->range() == NSRframe)
+	{
+		for (i = 0; i < itemsCount; ++i)
+		{
+			PageItem* currItem = Items->at(i);
+			if (currItem == NULL)
+				continue;
+			if (currItem->isTextFrame() && !currItem->isNoteFrame() && (currItem->itemText.length() > 0))
+			{
+				if (nStyle->isEndNotes() && nStyle->range() == NSRstory)
+				{
+					endNF = endNoteFrame(nStyle, (void*) currItem);
+					if (endNF != NULL)
+						clearNotesInFrameList(endNF);
+				}
+				if (!currItem->asTextFrame()->isValidChainFromBegin())
+				{
+					currItem->layout();
+					if (flag_restartMarksRenumbering)
+					{
+						//restart whole update as items was changed
+						if (endNF != NULL)
+							clearNotesInFrameList(endNF);
+						i = -1;
+						itemsCount = Items->count();
+						docWasChanged = true;
+						flag_restartMarksRenumbering = false;
+						continue;
+					}
+				}
+				if (nStyle->range() == NSRstory)
+				{
+					//restart numeration for all first frames of story chain
+					if (currItem->prevInChain() == NULL)
+					{
+						num = nStyle->start();
+						PageItem* nextItem = currItem;
+						while (nextItem != NULL)
+						{
+							if (nStyle->isEndNotes() || nextItem->asTextFrame()->hasNoteFrame(nStyle, false))
+								updateItemNotesNums(nextItem->asTextFrame(), nStyle, num);
+							nextItem = nextItem->nextInChain();
+						}
+					}
+				}
+				else	//restart numeration for each frame
+				{
+					num = nStyle->start();
+					if (nStyle->isEndNotes() || currItem->asTextFrame()->hasNoteFrame(nStyle, false))
+						updateItemNotesNums(currItem->asTextFrame(), nStyle, num);
+				}
+				if (currItem->asTextFrame()->hasNoteFrame(nStyle, false) && currItem->asTextFrame()->itemNoteFrame(nStyle)->invalid)
+					docWasChanged = true;
+				if (currItem->invalid)
+				{
+					currItem->layout();
+					docWasChanged = true;
+				}
+			}
+		}
+	}
+	else if (nStyle->range() == NSRpage)
+	{
+		for (int page = 0; page < Pages->count(); ++page)
+		{
+			if (nStyle->isEndNotes() && nStyle->range() == NSRpage)
+			{
+				endNF = endNoteFrame(nStyle, (void*) DocPages.at(page));
+				if (endNF != NULL)
+					clearNotesInFrameList(endNF);
+			}
+			//restart numeration for each page
+			num = nStyle->start();
+
+			for (i = 0; i < itemsCount; ++i)
+			{
+				PageItem* currItem = Items->at(i);
+				if (currItem == NULL)
+					continue;
+				if ((currItem->OwnPage == page) && currItem->isTextFrame() && !currItem->isNoteFrame() && (currItem->itemText.length() > 0))
+				{
+					if (!currItem->asTextFrame()->isValidChainFromBegin())
+					{
+						currItem->layout();
+						if (flag_restartMarksRenumbering)
+						{
+							//restart whole update as items was changed
+							if (endNF != NULL)
+								clearNotesInFrameList(endNF);
+							page = -1;
+							i = -1;
+							itemsCount = Items->count();
+							num = nStyle->start();
+							docWasChanged = true;
+							flag_restartMarksRenumbering = false;
+							break;
+						}
+					}
+					if (nStyle->isEndNotes() || currItem->asTextFrame()->hasNoteFrame(nStyle, false))
+						updateItemNotesNums(currItem->asTextFrame(), nStyle, num);
+					if (currItem->asTextFrame()->hasNoteFrame(nStyle, false) && currItem->asTextFrame()->itemNoteFrame(nStyle)->invalid)
+						docWasChanged = true;
+					if (currItem->invalid)
+					{
+						currItem->layout();
+						docWasChanged = true;
+					}
+				}
+			}
+			if ((i != -1) && (num == nStyle->start()) && nStyle->isEndNotes())
+			{
+				PageItem_NoteFrame* nF = endNoteFrame(nStyle);
+				if (nF != NULL && nF->isAutoNoteFrame())
+					nF->deleteIt = true;
+			}
+		}
+	}
+	flag_layoutNotesFrames = true;
+	return docWasChanged;
+}
+
+bool ScribusDoc::updateEndNotesNums()
+{
+	bool docWasChange = false;
+	foreach (NotesStyle* ns, m_docNotesStylesList)
+	{
+		if (ns->isEndNotes())
+		{
+			if (updateNotesNums(ns))
+				docWasChange = true;
+		}
+	}
+	return docWasChange;
+}
+
+void ScribusDoc::updateNotesFramesStyles(NotesStyle *nStyle)
+{
+	for (int i=0; i<Items->count(); ++i)
+	{
+		PageItem* item = Items->at(i);
+		if (item->isNoteFrame() && (item->asNoteFrame()->notesStyle() == nStyle) && !item->asNoteFrame()->deleteIt)
+		{
+			ParagraphStyle newStyle;
+			if (nStyle->notesParStyle().isEmpty() || (nStyle->notesParStyle() == tr("No Style")))
+			{
+				if (nStyle->isEndNotes())
+					//set default doc style
+					newStyle.setParent(paragraphStyles()[0].name());
+				else
+				{
+					if (item->asNoteFrame()->masterFrame() != NULL)
+					{
+						//set back style from master frame
+						newStyle.setParent(item->asNoteFrame()->masterFrame()->itemText.defaultStyle().parent());
+						newStyle.applyStyle(item->asNoteFrame()->masterFrame()->currentStyle());
+					}
+					else
+						newStyle.setParent(item->itemText.defaultStyle().parent());
+				}
+			}
+			else
+				newStyle.setParent(nStyle->notesParStyle());
+			item->itemText.setDefaultStyle(newStyle);
+			item->asTextFrame()->invalidateLayout(true);
+		}
+	}
+}
+
+void ScribusDoc::updateItemNotesFramesStyles(PageItem* item, ParagraphStyle newStyle)
+{
+	if (item->isTextFrame() && !item->isNoteFrame())
+	{
+		item = item->firstInChain();
+
+		while (item != NULL)
+		{
+			foreach (PageItem_NoteFrame* nF, item->asTextFrame()->notesFramesList())
+			{
+				NotesStyle* nSet = nF->notesStyle();
+				if (nSet->isEndNotes())
+					continue;
+				if (nSet->notesParStyle().isEmpty() || (nSet->notesParStyle() == tr("No Style")))
+				{
+					nF->itemText.setDefaultStyle(newStyle);
+					//nF->itemText.applyCharStyle(0, nF->itemText.length(), newStyle.charStyle());
+				}
+				setNotesChanged(true);
+			}
+			item = item->nextInChain();
+		}
+	}
+}
+
+QList<PageItem_NoteFrame *> ScribusDoc::listNotesFrames(NotesStyle *NS)
+{
+	QList<PageItem_NoteFrame *> list;
+	foreach(PageItem* item, DocItems)
+	{
+		if (item->isNoteFrame() && item->asNoteFrame()->notesStyle() == NS)
+			list.append(item->asNoteFrame());
+	}
+	return list;
+}
+
+const ScPage *ScribusDoc::page4EndNotes(NotesStyle *NS, PageItem* item)
+{
+	ScPage* scP = NULL;
+	if ((NS->range() == NSRdocument) || ((NS->range() == NSRsection) && docPrefsData.docSectionMap.isEmpty()))
+		scP = DocPages.last();
+	else if (item != NULL)
+	{
+		if (NS->range() == NSRpage)
+			scP = DocPages.at(item->OwnPage);
+		else if (NS->range() == NSRsection)
+		{
+			int section = getSectionKeyForPageIndex(item->OwnPage);
+			DocumentSection sec = sections().find(section).value();
+			scP = DocPages.at(sec.toindex);
+		}
+		else if (NS->range() == NSRstory)
+			scP = DocPages.at(item->lastInChain()->OwnPage);
+	}
+
+	return scP;
+}
+
+bool ScribusDoc::notesFramesUpdate()
+{
+	bool removeEmptyNF = false;
+	bool docWasChanged = false;
+	int end = 0;
+	do {
+		setNotesChanged(false);
+		end = Items->count();
+		for (int i = 0; i < end; ++i)
+		{
+			PageItem* item = Items->at(i);
+			if (!item->isTextFrame())
+				continue;
+			if (item->isNoteFrame())
+			{
+				if (item->asNoteFrame()->notesList().isEmpty())
+				{
+					if (item->isAutoNoteFrame())
+						item->asNoteFrame()->deleteIt = true;
+				}
+				else
+				{
+					if (item->asNoteFrame()->isEndNotesFrame())
+						updateEndNotesFrameContent(item->asNoteFrame());
+					else
+					{
+						if (item->itemText.length() == 0 && !item->asNoteFrame()->notesList().isEmpty())
+							item->asNoteFrame()->updateNotes(item->asNoteFrame()->notesList(), true);
+						item->invalid = true;
+						item->layout();
+					}
+				}
+				if (item->asNoteFrame()->deleteIt)
+					removeEmptyNF = true;
+			}
+			if (end != Items->count())
+			{
+				end = Items->count();
+				setNotesChanged(true);
+			}
+			docWasChanged = docWasChanged || notesChanged();
+			if (notesChanged())
+				break;
+		}
+	} while (notesChanged());
+
+	if (removeEmptyNF)
+	{
+		end = Items->count();
+		QList<PageItem*> tmplist;
+		for (int i = 0; i < end; ++i)
+		{
+			PageItem* item = Items->at(i);
+			if (item->isAutoNoteFrame() && item->asNoteFrame()->deleteIt)
+				tmplist.append(item);
+		}
+		foreach (PageItem* item, tmplist)
+		{
+			if (item->asNoteFrame()->masterFrame())
+				item->asNoteFrame()->masterFrame()->invalid = true;
+			delNoteFrame(item->asNoteFrame());
+		}
+		docWasChanged = true;
+	}
+	return docWasChanged;
+}
+
+void ScribusDoc::updateNotesFramesSettings(NotesStyle *NS)
+{
+	foreach (PageItem_NoteFrame* nF, listNotesFrames(NS))
+	{
+		if (nF->isWelded() && !NS->isAutoWeldNotesFrames())
+			nF->unWeld();
+		if (!nF->isWelded() && NS->isAutoWeldNotesFrames())
+		{
+			nF->setYPos(nF->masterFrame()->yPos() + nF->masterFrame()->height());
+			nF->setXPos(nF->masterFrame()->xPos());
+			nF->addWelded(nF->masterFrame());
+			nF->masterFrame()->addWelded(nF);
+			nF->masterFrame()->setWeldPoint(0, nF->masterFrame()->height(), nF);
+			nF->setWeldPoint(0,0, nF->masterFrame());
+			nF->invalidateLayout(false);
+		}
+		nF->setSizeVLocked(NS->isAutoNotesHeight());
+		nF->setSizeHLocked(NS->isAutoNotesWidth());
+		nF->setSizeLocked(NS->isAutoNotesHeight() && NS->isAutoNotesWidth());
+		if (NS->isAutoNotesHeight() || NS->isAutoNotesWidth())
+			nF->invalidateLayout(false);
+	}
+}
+
+void ScribusDoc::updateEndnotesFrames(NotesStyle* nStyle, bool invalidate)
+{
+	if (m_docEndNotesFramesMap.isEmpty())
+		return;
+	if (nStyle == NULL)
+	{
+		int NScount = m_docNotesStylesList.count();
+		for (int i=0; i < NScount; ++i)
+			updateEndnotesFrames(m_docNotesStylesList.at(i));
+	}
+	else if (nStyle->isEndNotes())
+	{
+		foreach (PageItem_NoteFrame* nF, listNotesFrames(nStyle))
+			updateEndNotesFrameContent(nF);
+	}
+	flag_updateEndNotes = false;
+}
+
+//for sorting purpose
+bool ascendingSort(TextNote* nt1, TextNote* nt2) { return nt1->num() < nt2->num(); }
+
+void ScribusDoc::updateEndNotesFrameContent(PageItem_NoteFrame *nF, bool invalidate)
+{
+	QList<TextNote*> nList;
+	foreach (PageItem* item, DocItems)
+	{
+		if (item->isTextFrame() && !item->isNoteFrame())
+		{
+			QList<TextNote*> nL = item->asTextFrame()->notesList(nF);
+			if (!nL.isEmpty())
+				nList.append(nL);
+			if (invalidate)
+				item->invalid = true;
+		}
+	}
+
+	if (nList.isEmpty())
+	{
+		if (nF->isAutoNoteFrame())
+		{
+			nF->deleteIt = true;
+			m_docNotesInFrameMap.remove(nF);
+			delNoteFrame(nF);
+		}
+	}
+	else
+	{
+		NotesStyle* currNS = nF->notesStyle();
+		if (currNS->isAutoNotesHeight() || currNS->isAutoNotesWidth())
+			nF->invalidateLayout(false);
+		qSort(nList.begin(), nList.end(), ascendingSort);
+		if (nList == m_docNotesInFrameMap.value(nF))
+			return;
+
+		nF->updateNotes(nList);
+		nF->invalid = true;
+		nF->layout();
+		//layout all endnotes frames with same range
+		foreach (NotesStyle* NS, m_docNotesStylesList)
+		{
+			if ((NS != currNS) && (NS->isEndNotes() && NS->range() == currNS->range()))
+				foreach (PageItem_NoteFrame* NF, listNotesFrames(NS))
+					NF->layout();
+		}
+		m_docNotesInFrameMap.insert(nF, nList);
+	}
+}
+
+void ScribusDoc::updateChangedEndNotesFrames()
+{
+	while (!m_docEndNotesFramesChanged.isEmpty())
+	{
+		PageItem_NoteFrame* nF = m_docEndNotesFramesChanged.first();
+		m_docEndNotesFramesChanged.removeAll(nF);
+		updateEndNotesFrameContent(nF);
+		if (nF->deleteIt && nF->isAutoNoteFrame())
+			delNoteFrame(nF);
+	}
+}
+
+PageItem_NoteFrame *ScribusDoc::createNoteFrame(PageItem_TextFrame *inFrame, NotesStyle *nStyle, int index)
+{
+	PageItem_NoteFrame* nF = new PageItem_NoteFrame(inFrame, nStyle);
+	if (nStyle->isEndNotes())
+		m_docEndNotesFramesMap.insert(nF, rangeItem());
+	m_docNotesInFrameMap.insert(nF, QList<TextNote*>());
+	if (index > -1)
+		DocItems.insert(index, nF);
+	else
+		DocItems.append(nF);
+	return nF;
+}
+
+PageItem_NoteFrame *ScribusDoc::createNoteFrame(NotesStyle *nStyle, double x, double y, double w, double h, double w2, QString fill, QString outline)
+{
+	PageItem_NoteFrame* nF = new PageItem_NoteFrame(nStyle, this, x, y, w, h, w2, fill, outline);
+	if (nStyle->isEndNotes())
+		m_docEndNotesFramesMap.insert(nF, rangeItem());
+	m_docNotesInFrameMap.insert(nF, QList<TextNote*>());
+	DocItems.append(nF);
+	return nF;
+}
+
+void ScribusDoc::delNoteFrame(PageItem_NoteFrame* nF, bool removeMarks, bool forceDeletion)
+{
+	Q_ASSERT(nF != NULL);
+	//check if note frame is listed in text frames m_notesFramesMap
+	if (nF->itemText.length() > 0 && removeMarks)
+		nF->removeMarksFromText(false);
+		
+	if (appMode == modeEdit && nF->isSelected())
+	{
+		view()->Deselect(true);
+		if (!nF->isEndNotesFrame())
+			view()->SelectItem(nF->masterFrame());
+	}
+	if (m_docEndNotesFramesMap.contains(nF))
+	{
+		m_docEndNotesFramesMap.remove(nF);
+		m_docEndNotesFramesChanged.removeAll(nF);
+		foreach (TextNote* note, nF->notesList())
+		{
+			note->masterMark()->getItemPtr()->asTextFrame()->removeNoteFrame(nF);
+			note->masterMark()->getItemPtr()->invalid = true;
+		}
+	}
+	else if (nF->masterFrame() != NULL)
+	{
+		nF->masterFrame()->removeNoteFrame(nF);
+		nF->masterFrame()->invalid = true;
+	}
+	m_docNotesInFrameMap.remove(nF);
+
+	nF->dropLinks();
+	if (nF->isWelded())
+		nF->unWeld(!nF->isAutoNoteFrame());
+	//delete marks pointed to that item
+	for (int a=0; a < m_docMarksList.count(); ++a)
+	{
+		Mark* m = m_docMarksList.at(a);
+		Q_ASSERT(m != NULL);
+		if (m->isType(MARK2ItemType) && (m->getItemPtr() == nF))
+		{
+			setUndoDelMark(m);
+			eraseMark(m,true);
+		}
+	}
+	m_Selection->delaySignalsOn();
+	if (m_Selection->findItem(nF)!=-1)
+	{
+		if (appMode == modeEdit)
+			view()->requestMode(modeNormal);
+		m_Selection->removeItem(nF);
+		if (m_Selection->isEmpty() && nF->masterFrame())
+			m_Selection->addItem(nF->masterFrame());
+	}
+	m_Selection->delaySignalsOff();
+
+	Items->removeOne(nF);
+	setNotesChanged(true);
+	if (forceDeletion)
+		delete nF;
+}
+
+bool ScribusDoc::validateNSet(NotesStyle NS, QString newName)
+{
+	//check if choosen numbering type is avaiable with choosen range, prefix and suffix
+	QString errStr = QString();
+	foreach (NotesStyle* NS2, m_docNotesStylesList)
+	{
+		if (newName.isEmpty())
+			//hack for validate nset while its name will change
+			newName = NS.name();
+		if (newName == NS2->name())
+			continue;
+		if (NS.range() == NS2->range())
+		{
+				if ((NS.getType() == NS2->getType()) && (NS.prefix() == NS2->prefix()) && (NS.suffix() == NS2->suffix()))
+					errStr.append(NS.name() + tr("Notes style has document as range and provide same numbering style as set ") + NS2->name() + "\n");
+		}
+	}
+
+	if (!errStr.isEmpty() && ScCore->usingGUI())
+	{
+		ScMessageBox::warning(this->scMW(), QObject::tr("Unaceptable settings for Notes Style"), "<qt>"+ errStr +"</qt>", QMessageBox::Ok, QMessageBox::Abort | QMessageBox::Default);
+		return false;
+	}
+	return true;
+}
+
+void ScribusDoc::invalidateNoteFrames(NotesStyle *nStyle)
+{
+	foreach (PageItem_NoteFrame* nF, listNotesFrames(nStyle))
+		nF->invalid = true;
+}
+
+void ScribusDoc::invalidateMasterFrames(NotesStyle *nStyle)
+{
+	QList<PageItem*> toInvalidate;
+	foreach (TextNote* note, m_docNotesList)
+	{
+		if (note->notesStyle() == nStyle)
+			toInvalidate.append(note->masterMark()->getItemPtr());
+	}
+	while (!toInvalidate.isEmpty())
+		toInvalidate.takeFirst()->invalid = true;
+}
+
+PageItem_NoteFrame *ScribusDoc::endNoteFrame(NotesStyle *nStyle, PageItem_TextFrame *master)
+{
+	if (nStyle->range() == NSRdocument)
+		return endNoteFrame(nStyle);
+	else if (nStyle->range() == NSRsection)
+		return endNoteFrame(nStyle, getSectionKeyForPageIndex(master->OwnPage));
+	else if (nStyle->range() == NSRpage)
+		return endNoteFrame(nStyle, (void*) DocPages.at(master->OwnPage));
+	else if (nStyle->range() == NSRstory)
+		return endNoteFrame(nStyle, master->firstInChain());
+	return NULL;
+}
+
+PageItem_NoteFrame* ScribusDoc::endNoteFrame(NotesStyle *nStyle, int sectIndex)
+{
+	if (nStyle->range() != NSRsection)
+		return NULL;
+	if (m_docEndNotesFramesMap.isEmpty())
+		return NULL;
+
+	QMap<PageItem_NoteFrame*, rangeItem>::Iterator it = m_docEndNotesFramesMap.begin();
+	QMap<PageItem_NoteFrame*, rangeItem>::Iterator end = m_docEndNotesFramesMap.end();
+	while (it != end)
+	{
+		PageItem_NoteFrame* nF = it.key();
+		if (nF->notesStyle() == nStyle)
+		{
+			rangeItem rItem = it.value();
+			if (rItem.sectionIndex == sectIndex)
+				return nF;
+		}
+		++it;
+	}
+	return NULL;
+}
+
+PageItem_NoteFrame* ScribusDoc::endNoteFrame(NotesStyle *nStyle, void* item)
+{
+	if (m_docEndNotesFramesMap.isEmpty())
+		return NULL;
+	if ((nStyle->range() != NSRdocument) && (item == NULL))
+		return NULL;
+
+	QMap<PageItem_NoteFrame*, rangeItem>::Iterator it = m_docEndNotesFramesMap.begin();
+	QMap<PageItem_NoteFrame*, rangeItem>::Iterator end = m_docEndNotesFramesMap.end();
+
+	while (it != end)
+	{
+		PageItem_NoteFrame* nF = it.key();
+		rangeItem rItem = it.value();
+
+		if (nF->notesStyle() == nStyle)
+		{
+			if ((nStyle->range() == NSRdocument) || (item == rItem.P))
+				return nF;
+		}
+		++it;
+	}
+	return NULL;
+}

Modified: trunk/Scribus/scribus/scribusdoc.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/scribusdoc.h
==============================================================================
--- trunk/Scribus/scribus/scribusdoc.h (original)
+++ trunk/Scribus/scribus/scribusdoc.h Sat Oct 27 15:56:36 2012
@@ -41,10 +41,13 @@
 #include "scribusapi.h"
 #include "colormgmt/sccolormgmtengine.h"
 #include "documentinformation.h"
+#include "marks.h"
+#include "notesstyles.h"
 #include "observable.h"
 #include "pageitem.h"
 #include "pageitem_group.h"
 #include "pageitem_latexframe.h"
+#include "pageitem_textframe.h"
 #include "pagestructs.h"
 #include "prefsstructs.h"
 #include "scguardedptr.h"
@@ -75,8 +78,10 @@
 class ScPattern;
 class UndoTransaction;
 class Serializer;
-
 class QProgressBar;
+class MarksManager;
+class NotesStyle;
+class TextNote;
 
 struct SCRIBUS_API NodeEditContext : public MassObservable<QPointF>
 {
@@ -784,8 +789,9 @@
 	\param w ?
 	\param fill fill color name
 	\param outline outline color name
+	\param noteFrame optional (default false) indicates that noteframes should be created, not text frame
 	*/
-	int itemAdd(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, const double x, const double y, const double b, const double h, const double w, const QString& fill, const QString& outline, const bool itemFinalised);
+	int itemAdd(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, const double x, const double y, const double b, const double h, const double w, const QString& fill, const QString& outline, const bool itemFinalised, const bool noteFrame = false);
 
 	/** Add an item to the page based on the x/y position. Item will be fitted to the closest guides/margins */
 	int itemAddArea(const PageItem::ItemType itemType, const PageItem::ItemFrameType frameType, const double x, const double y, const double w, const QString& fill, const QString& outline, const bool itemFinalised);
@@ -978,6 +984,11 @@
 	 * 
 	 */
 	void setFirstSectionFromFirstPageNumber();
+	/**
+	 * @param pageIndex page nr
+	 * @brief Returns name of section where page is located
+	 */
+	QString getSectionNameForPageIndex(const uint pageIndex) const;
 
 	//! @brief Some internal align tools
 	typedef enum {alignFirst, alignLast, alignPage, alignMargins, alignGuide, alignSelection } AlignTo;
@@ -1618,6 +1629,136 @@
 	void updatePict(QString name);
 	void updatePictDir(QString name);
 	void removePict(QString name);
+
+// Marks and notes
+public:
+	/**
+	 * Explanation
+	 * master frame - text frame with marks for notes
+	 * notesframe - frame with notes
+	 * master & note mark - master is mark in "master" text, note mark is at begining of note in noteframe
+	 */
+	
+	//return page where endnotesframe should be located depending of notes style range and location of master mark
+	const ScPage* page4EndNotes(NotesStyle* NS, PageItem* item);
+
+	//data handling structures
+private:
+	QList<Mark*> m_docMarksList;
+	QList<TextNote*> m_docNotesList;
+	//flags used for indicating needs of updates
+	bool flag_notesChanged;
+
+public:
+	const QList<Mark*> marksList() { return m_docMarksList; }
+	const QList<TextNote*> notesList() { return m_docNotesList; }
+	QList<NotesStyle*> m_docNotesStylesList;
+	QMap<PageItem_NoteFrame*, rangeItem> m_docEndNotesFramesMap;
+	QList<NotesStyle*> ns2Update; //list of notes styles to update
+
+	//returns list of notesframes for given Notes Style
+	QList<PageItem_NoteFrame*> listNotesFrames(NotesStyle* NS);
+
+	//flags used for indicating needs of updates
+	bool notesChanged() { return flag_notesChanged; }
+	void setNotesChanged(bool on) { flag_notesChanged = on; }
+	bool flag_restartMarksRenumbering;
+	bool flag_updateMarksLabels;
+	bool flag_updateEndNotes;
+	bool flag_layoutNotesFrames;
+
+	//returns list of marks labels for given mark type
+	QStringList marksLabelsList(MarkType type);
+
+	//return mark definied with gioven label and given type
+	Mark* getMarkDefinied(QString label, MarkType type); //returns mark with label and type (labels are unique only for same type marks)
+	Mark* newMark(Mark* mrk = NULL);
+	TextNote* newNote(NotesStyle* NS);
+	
+	bool isMarkUsed(Mark* mrk, bool visible = false);
+	//set cursor in text where given mark will be found
+	void setCursor2MarkPos(Mark* mark);
+	//return false if mark was not found
+	bool eraseMark(Mark* mrk, bool fromText=false, PageItem* item=NULL, bool force = false); //force is used only for deleting non-unique marks by MarksManager
+	void setUndoDelMark(Mark* mrk);
+	//invalidate all text frames where given mark will found
+	//usefull spacially for varaible text marks after changing its text definition
+	//if forceUpdate then found master frames are relayouted
+	bool invalidateVariableTextFrames(Mark* mrk, bool forceUpdate = false); //returns if any text was changed
+
+	//for foot/endnotes
+	NotesStyle* newNotesStyle(NotesStyle NS);
+	void renameNotesStyle(NotesStyle* NS, QString newName);
+	//delete whole notes style with its notesframes and notes
+	void deleteNotesStyle(QString nsName);
+	void undoSetNotesStyle(SimpleState* ss, NotesStyle* ns);
+	NotesStyle* getNotesStyle(QString nsName);
+	//delete note, if fromText than marks for given note will be removed
+	void deleteNote(TextNote* note);
+	void setUndoDelNote(TextNote* note);
+	PageItem_NoteFrame* createNoteFrame(PageItem_TextFrame* inFrame, NotesStyle *nStyle, int index = -1);
+	PageItem_NoteFrame* createNoteFrame(NotesStyle *nStyle, double x, double y, double w, double h, double w2, QString fill, QString outline);
+	//delete noteframe
+	void delNoteFrame(PageItem_NoteFrame *nF, bool removeMarks=true, bool forceDeletion = true);
+	//renumber notes for given notes style
+	//return true if doc needs update after changing numbers of notes
+	bool updateNotesNums(NotesStyle* nStyle);
+	//set new text styles for notes marks
+	void updateNotesFramesStyles(NotesStyle* nStyle);
+	//check conflicts beetween notes styles
+	bool validateNSet(NotesStyle NS, QString newName = "");
+	//update layout remove empty notesframes
+	bool notesFramesUpdate();
+	//update notesframes after changing automatic features of notes style
+	void updateNotesFramesSettings(NotesStyle* NS);
+
+	//search for endnotesframe for given notes style and item holding master mark
+	PageItem_NoteFrame* endNoteFrame(NotesStyle* nStyle, PageItem_TextFrame* master);
+	//
+	void setEndNoteFrame(PageItem_NoteFrame* nF, void* ptr)   { rangeItem rI={ptr}; m_docEndNotesFramesMap.insert(nF,rI); }
+	void setEndNoteFrame(PageItem_NoteFrame* nF, int section)   { rangeItem rI; rI.sectionIndex = section; m_docEndNotesFramesMap.insert(nF, rI); }
+	//update all endnotesframes content for given notes style
+	void updateEndnotesFrames(NotesStyle* nStyle = NULL, bool invalidate = false);
+	//update endnotesframe content
+	void updateEndNotesFrameContent(PageItem_NoteFrame* nF, bool invalidate = false);
+	//insert noteframe into list of changed
+	void endNoteFrameChanged(PageItem_NoteFrame* nF) { m_docEndNotesFramesChanged.append(nF); }
+	//update content for changed endnotesframes
+	void updateChangedEndNotesFrames();
+	//finds mark position in text
+	//return true if mark was found, CPos is set for mark`s position
+	//if item==NULL then search in all items and if mark is found than item is set
+	int findMarkCPos(Mark* mrk, PageItem* &item, int Start = 0);
+	QList<PageItem_NoteFrame*> m_docEndNotesFramesChanged;
+
+	//finds item which holds given mark, start searching from next to lastItem index in DocItems
+	PageItem* findMarkItem(Mark* mrk, int &lastItem);
+	
+private:
+	//QMap<PageItem_NoteFrame*, QList<TextNote *> > map of notesframes and its list of notes
+	NotesInFrameMap m_docNotesInFrameMap;
+
+	PageItem* findFirstMarkItem(Mark* mrk) { int tmp = -1; return findMarkItem(mrk, tmp); }
+
+	//search for endnotesframe for given notes style and item holding master mark or section number
+	PageItem_NoteFrame* endNoteFrame(NotesStyle* nStyle, void* item = NULL);
+	PageItem_NoteFrame* endNoteFrame(NotesStyle* nStyle, int sectIndex);
+	//clear list of notes for given notesframe
+	void clearNotesInFrameList(PageItem_NoteFrame* nF) { m_docNotesInFrameMap.insert(nF, QList<TextNote*>()); }
+	//renumber notes with given notes style for given frame starting from number num
+	void updateItemNotesNums(PageItem_TextFrame *frame, NotesStyle* nStyle, int &num);
+	//update notesframes text styles
+	void updateItemNotesFramesStyles(PageItem *item, ParagraphStyle newStyle);
+	
+	//not used?
+	bool updateEndNotesNums(); //return true if doc needs update
+	void invalidateNoteFrames(NotesStyle* nStyle);
+	void invalidateMasterFrames(NotesStyle* nStyle);
+
+public slots:
+	//update strings (page numbers) for marks
+	bool updateMarks(bool updateNotesMarks = false);
+
 //welding two items
 public slots:
 	void itemSelection_UnWeld();

Modified: trunk/Scribus/scribus/scribusstructs.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/scribusstructs.h
==============================================================================
--- trunk/Scribus/scribus/scribusstructs.h (original)
+++ trunk/Scribus/scribus/scribusstructs.h Sat Oct 27 15:56:36 2012
@@ -278,7 +278,8 @@
 	FontNotEmbedded=15,
 	EmbeddedFontIsOpenType=16,
 	OffConflictLayers=17,
-	PartFilledImageFrame= 18
+	PartFilledImageFrame= 18,
+	MarksChanged = 19
 } PreflightError;
 
 typedef QMap<PreflightError, int> errorCodes;
@@ -366,6 +367,7 @@
 	reqCmsOptionsUpdate  = 512,
 	reqCustomShapeUpdate = 1024,
 	reqInlinePalUpdate   = 2048,
+	reqMarksUpdate       = 4096,
 	reqUpdateAll = 65535
 };
 

Modified: trunk/Scribus/scribus/scribusview.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/scribusview.cpp
==============================================================================
--- trunk/Scribus/scribus/scribusview.cpp (original)
+++ trunk/Scribus/scribus/scribusview.cpp Sat Oct 27 15:56:36 2012
@@ -904,7 +904,7 @@
 					cItem = b->asTextFrame();
 				if (cItem->HasSel)
 					cItem->deleteSelectedTextFromFrame();
-				cItem->invalidateLayout();
+				cItem->invalidateLayout(false);
 				cItem->itemText.insertObject(id);
 				if (b->isTable())
 					b->asTable()->update();
@@ -1753,7 +1753,7 @@
 	{
 		if (Doc->appMode == modeRotation)
 			qApp->changeOverrideCursor(QCursor(loadIcon("Rotieren2.png")));
-		else
+		else if (!currItem->sizeHLocked() && ! currItem->sizeVLocked())
 		{
 			double rr = fabs(currItem->rotation());
 			if (((rr >= 0.0) && (rr < 45.0)) || ((rr >= 135.0) && (rr < 225.0)) ||
@@ -2812,7 +2812,8 @@
 		for (int layerLevel = 0; layerLevel < layerCount; ++layerLevel)
 		{
 			Doc->Layers.levelToLayer(layer, layerLevel);
-			m_canvas->DrawPageItems(painter, layer, QRect(clipx, clipy, clipw, cliph));
+			m_canvas->DrawPageItems(painter, layer, QRect(clipx, clipy, clipw, cliph), false);
+			m_canvas->DrawPageItems(painter, layer, QRect(clipx, clipy, clipw, cliph), true);
 		}
 		painter->endLayer();
 		painter->end();
@@ -2943,7 +2944,8 @@
 			{
 				Doc->Layers.levelToLayer(layer, layerLevel);
 				m_canvas->DrawMasterItems(painter, Doc->DocPages.at(Nr), layer, QRect(clipx, clipy, clipw, cliph));
-				m_canvas->DrawPageItems(painter, layer, QRect(clipx, clipy, clipw, cliph));
+				m_canvas->DrawPageItems(painter, layer, QRect(clipx, clipy, clipw, cliph), false);
+				m_canvas->DrawPageItems(painter, layer, QRect(clipx, clipy, clipw, cliph), true);
 			}
 			painter->endLayer();
 			painter->end();

Modified: trunk/Scribus/scribus/sctextstruct.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/sctextstruct.cpp
==============================================================================
--- trunk/Scribus/scribus/sctextstruct.cpp (original)
+++ trunk/Scribus/scribus/sctextstruct.cpp Sat Oct 27 15:56:36 2012
@@ -32,12 +32,25 @@
 	if (parstyle)
 		delete parstyle;
 	parstyle = NULL;
+	mark = NULL;
 }
 
 bool ScText::hasObject(ScribusDoc *doc) const
 {
 	if (this->ch == SpecialChars::OBJECT)
 		return ((embedded > 0) && (doc->FrameItems.contains(embedded)));
+	return false;
+}
+
+bool ScText::hasMark(Mark* MRK) const
+{
+	if (this->ch == SpecialChars::OBJECT)
+	{
+		if (MRK == NULL)
+			return mark != NULL;
+		else
+			return mark == MRK;
+	}
 	return false;
 }
 
@@ -60,3 +73,9 @@
 		return doc->FrameItems[embedded];
 	return NULL;
 }
+
+void ScText::setNewMark(Mark *mrk)
+{
+	if (!mrk->isUnique())
+		mark = mrk;
+}

Modified: trunk/Scribus/scribus/sctextstruct.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/sctextstruct.h
==============================================================================
--- trunk/Scribus/scribus/sctextstruct.h (original)
+++ trunk/Scribus/scribus/sctextstruct.h Sat Oct 27 15:56:36 2012
@@ -28,6 +28,7 @@
 #include "styles/paragraphstyle.h"
 
 class PageItem;
+class Mark;
 class ScribusDoc;
 
 /* Struktur fuer Pageitem Text */
@@ -110,16 +111,17 @@
 	float PRot;
 	float PDx;
 	int embedded;
+	Mark* mark;
 	QChar ch;
 	ScText() : 
 		CharStyle(),
 		parstyle(NULL), glyph(), 
-		PtransX(0.0f), PtransY(0.0f), PRot(0.0f), PDx(0.0f), embedded(0), ch() {}
+		PtransX(0.0f), PtransY(0.0f), PRot(0.0f), PDx(0.0f), embedded(0), mark(NULL), ch() {}
 	ScText(const ScText& other) : 
 		CharStyle(other),
 		parstyle(NULL), glyph(other.glyph), 
 		PtransX(other.PtransX), PtransY(other.PtransY), PRot(other.PRot), PDx(other.PDx), 
-		embedded(other.embedded), ch(other.ch)
+		embedded(other.embedded), mark(NULL), ch(other.ch)
 	{
 		glyph.more = NULL;
 		GlyphLayout *layout = &glyph;
@@ -132,12 +134,18 @@
 		}
 		if (other.parstyle)
 			parstyle = new ParagraphStyle(*other.parstyle);
+		if (other.mark)
+			setNewMark(other.mark);
 	}
 	~ScText();
 
 	bool hasObject(ScribusDoc *doc) const;
+	//returns true if given MRK is found, if MRK is NULL then any mark returns true
+	bool hasMark(Mark * MRK = NULL) const;
 	QList<PageItem*> getGroupedItems(ScribusDoc *doc);
 	PageItem* getItem(ScribusDoc *doc);
+private:
+	void setNewMark(Mark* mrk);
 };
 #endif
 

Modified: trunk/Scribus/scribus/serializer.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/serializer.h
==============================================================================
--- trunk/Scribus/scribus/serializer.h (original)
+++ trunk/Scribus/scribus/serializer.h Sat Oct 27 15:56:36 2012
@@ -53,7 +53,7 @@
 		elements. Since it has Digester as a superclass, a Serializer object can
 	    also be used where a SaxHandler is required as argument, eg. the saxx() method.
 	 */
-	Serializer(ScribusDoc& doc);
+	Serializer(ScribusDoc& doc); //saxing notes needs doc
 	/**
 	  Writes all objects in selection to handler as a fragment. Needed styles and colors
 	  are included.

Modified: trunk/Scribus/scribus/tablecell.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/tablecell.cpp
==============================================================================
--- trunk/Scribus/scribus/tablecell.cpp (original)
+++ trunk/Scribus/scribus/tablecell.cpp Sat Oct 27 15:56:36 2012
@@ -143,7 +143,7 @@
 	d->textFrame->setXYPos(contentRect.x(), contentRect.y(), true);
 	d->textFrame->setWidthHeight(contentRect.width(), contentRect.height(), true);
 	d->textFrame->updateClip();
-	d->textFrame->invalidateLayout();
+	d->textFrame->invalidateLayout(false);
 }
 
 void TableCell::setText(const QString& text)

Modified: trunk/Scribus/scribus/text/storytext.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/text/storytext.cpp
==============================================================================
--- trunk/Scribus/scribus/text/storytext.cpp (original)
+++ trunk/Scribus/scribus/text/storytext.cpp Sat Oct 27 15:56:36 2012
@@ -26,9 +26,11 @@
 #include <QList>
 #include <cassert>  //added to make Fedora-5 happy
 #include "fpoint.h"
+#include "notesstyles.h"
 #include "scfonts.h"
 #include "scribusdoc.h"
 #include "sctext_shared.h"
+#include "selection.h"
 #include "storytext.h"
 #include "scribus.h"
 #include "util.h"
@@ -327,6 +329,7 @@
 		else if (other.text(i) == SpecialChars::OBJECT) {
 			insertChars(pos, SpecialChars::OBJECT);
 			item(pos)->embedded = other.item(i)->embedded;
+			item(pos)->mark = other.item(i)->mark;
 			applyCharStyle(pos, 1, other.charStyle(i));
 			cstyleStart = i+1;
 			pos += 1;
@@ -632,6 +635,17 @@
 	doc->FrameItems[ob]->OwnPage = -1; // #10379: OwnPage is not meaningful for inline object
 }
 
+void StoryText::insertMark(Mark* Mark, int pos)
+{
+	if (Mark == NULL)
+		return;
+	if (pos < 0)
+		pos = d->cursorPosition;
+
+	insertChars(pos, SpecialChars::OBJECT, false);
+	const_cast<StoryText *>(this)->d->at(pos)->mark = Mark;
+}
+
 void StoryText::replaceObject(int pos, int ob)
 {
 	if (pos < 0)
@@ -761,6 +775,32 @@
 	return that->d->at(pos)->getItem(doc);
 }
 
+bool StoryText::hasMark(int pos) const
+{
+	if (pos < 0)
+		pos += length();
+
+	assert(pos >= 0);
+	assert(pos < length());
+
+	StoryText* that = const_cast<StoryText *>(this);
+	if (that->d->at(pos)->ch == SpecialChars::OBJECT)
+		return that->d->at(pos)->hasMark();
+	return false;
+}
+
+Mark* StoryText::mark(int pos) const
+{
+	if (pos < 0)
+		pos += length();
+
+	assert(pos >= 0);
+	assert(pos < length());
+
+	StoryText* that = const_cast<StoryText *>(this);
+	return that->d->at(pos)->mark;
+}
+
 const CharStyle & StoryText::charStyle() const
 {
 	return charStyle(d->cursorPosition);
@@ -782,9 +822,11 @@
 		qDebug() << "storytext::charstyle: access at end of text %i" << pos;
 		--pos;
 	}
+	//for notes frames - get style from note text, not from mark
+	if ((pos+1 < length()) && hasMark(pos) && mark(pos)->isNoteType())
+		++pos;
 	if (text(pos) == SpecialChars::PARSEP)
 		return paragraphStyle(pos).charStyle();
-	
 	StoryText* that = const_cast<StoryText *>(this);
 	return dynamic_cast<const CharStyle &> (*that->d->at(pos));
 }
@@ -1464,7 +1506,13 @@
 
 int StoryText::lengthOfSelection() const
 {
-	return selFirst <= selLast? selLast - selFirst + 1 : 0;
+	//FIX ME - sometimes I saw values equal or greater than length of text
+	int last = selLast;
+	if (selFirst >= length())
+		return 0;
+	if (selLast >= length())
+		last = length() -1;
+	return selFirst <= last? last - selFirst + 1 : 0;
 }
 
 
@@ -1634,6 +1682,8 @@
 		if (par)
 			par->charStyleContext()->invalidate();
 	}
+	if (!signalsBlocked())
+		emit changed();
 	emit changed();
 }
 
@@ -1868,6 +1918,38 @@
 		{
 			object(i)->saxx(handler);
 		}
+		else if (hasMark(i))
+		{
+			Mark* mrk = mark(i);
+			if ((doc->m_Selection->itemAt(0)->isNoteFrame() && mrk->isType(MARKNoteMasterType))
+				|| (!doc->m_Selection->itemAt(0)->isTextFrame() && mrk->isType(MARKNoteFrameType)))
+				continue; //do not insert notes marks into text frames nad vice versa
+			Xml_attr mark_attr;
+			mark_attr.insert("label", mrk->label);
+			mark_attr.insert("typ", QString::number((int )mrk->getType()));
+			if (mrk->isType(MARK2ItemType) && (mrk->getItemPtr() != NULL))
+				mark_attr.insert("item", mrk->getItemPtr()->itemName());
+			else if (mrk->isType(MARK2MarkType))
+			{
+				QString l;
+				MarkType t;
+				mrk->getMark(l, t);
+				if (doc->getMarkDefinied(l,t) != NULL)
+				{
+					mark_attr.insert("mark_l", l);
+					mark_attr.insert("mark_t", QString::number((int) t));
+				}
+			}
+			else if (mrk->isType(MARKNoteMasterType))
+			{
+				mark_attr.insert("nStyle", mrk->getNotePtr()->notesStyle()->name());
+				mark_attr.insert("note",mrk->getNotePtr()->saxedText());
+				//store noteframe name for inserting into note if it is non-auto-removable
+				if (!mrk->getNotePtr()->noteMark()->getItemPtr()->isAutoNoteFrame())
+					mark_attr.insert("noteframe", mrk->getNotePtr()->noteMark()->getItemPtr()->getUName());
+			}
+			handler.beginEnd("mark", mark_attr);
+		}
 		else if (curr == SpecialChars::TAB)
 		{
 			handler.beginEnd("tab", empty);
@@ -2028,6 +2110,92 @@
 struct AppendInlineFrame : public MakeAction<AppendInlineFrame_body>
 {};
 
+//marks support
+class AppendMark_body : public Action_body
+{
+public:
+	void begin(const Xml_string& tag, Xml_attr attr)
+	{
+		StoryText* story = this->dig->top<StoryText>();
+		QString l = "";
+		MarkType t = MARKNoType;
+		
+		Mark* mrk = NULL;
+		
+		if (tag == "mark")
+		{
+			Xml_attr::iterator lIt = attr.find("label");
+			Xml_attr::iterator tIt = attr.find("typ");
+			Xml_attr::iterator iIt = attr.find("item");
+			Xml_attr::iterator m_lIt = attr.find("mark_l");
+			Xml_attr::iterator m_tIt = attr.find("mark_t");
+			Xml_attr::iterator nf_It = attr.find("noteframe");
+			if (lIt != attr.end())
+				l = Xml_data(lIt);
+			if (tIt != attr.end())
+				t = (MarkType) parseInt(Xml_data(tIt));
+			ScribusDoc* doc  = this->dig->lookup<ScribusDoc>("<scribusdoc>");
+			if (t == MARKVariableTextType)
+				mrk = doc->getMarkDefinied(l,t);
+			else
+			{
+				mrk = doc->newMark();
+				getUniqueName(l,doc->marksLabelsList(t), "_");
+				mrk->label = l;
+				mrk->OwnPage = doc->currentPage()->pageNr();
+				mrk->setType(t);
+				if (mrk->isType(MARK2ItemType) && (iIt != attr.end()))
+				{
+					PageItem* item = doc->getItemFromName(Xml_data(iIt));
+					mrk->setItemPtr(item);
+					if (item == NULL)
+						mrk->setString("0");
+					else
+						mrk->setString(QString::number(item->OwnPage));
+					mrk->setItemName(Xml_data(iIt));
+				}
+				if (mrk->isType(MARK2MarkType) && (m_lIt != attr.end()) && (m_tIt != attr.end()))
+				{
+					Mark* targetMark = doc->getMarkDefinied(Xml_data(m_lIt), (MarkType) parseInt(Xml_data(m_tIt)));
+					mrk->setMark(targetMark);
+					if (targetMark == NULL)
+						mrk->setString("0");
+					else
+						mrk->setString(QString::number(targetMark->OwnPage));
+					mrk->setItemName(Xml_data(m_lIt));
+				}
+				if (mrk->isType(MARKNoteMasterType))
+				{
+					Xml_attr::iterator nIt = attr.find("note");
+					Xml_attr::iterator nsIt = attr.find("nStyle");
+					NotesStyle* NS;
+					if (nsIt == attr.end())
+						NS = doc->m_docNotesStylesList.at(0);
+					else
+						NS = doc->getNotesStyle(Xml_data(nsIt));
+					TextNote* note = doc->newNote(NS);
+					note->setMasterMark(mrk);
+					if (nIt != attr.end())
+						note->setSaxedText(Xml_data(nIt));
+//					if (!NS->isAutoRemoveEmptyNotesFrames() && (nf_It != attr.end()))
+//					{
+//						PageItem_NoteFrame* nF = (PageItem_NoteFrame*) doc->getItemFromName(Xml_data(nf_It));
+//						if (nF != NULL)
+//							doc->m_Selection->itemAt(0)->asTextFrame()->setNoteFrame(nF);
+//					}
+					mrk->setNotePtr(note);
+					doc->setNotesChanged(true);
+				}
+				doc->newMark(mrk);
+			}
+			story->insertMark(mrk);
+		}
+	}
+};
+
+struct AppendMark : public MakeAction<AppendMark_body>
+{};
+
 /*
 class ApplyStyle_body : public Action_body
 {
@@ -2252,5 +2420,6 @@
 	
 	//PageItem::desaxeRules(storyPrefix, ruleset); argh, that would be recursive!
 	ruleset.addRule(Digester::concat(spanPrefix, "item"), AppendInlineFrame() );
-	
-}
+	ruleset.addRule(Digester::concat(spanPrefix, "mark"), AppendMark() );
+	
+}

Modified: trunk/Scribus/scribus/text/storytext.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/text/storytext.h
==============================================================================
--- trunk/Scribus/scribus/text/storytext.h (original)
+++ trunk/Scribus/scribus/text/storytext.h Sat Oct 27 15:56:36 2012
@@ -30,6 +30,7 @@
 #include <QList>
 #include <cassert>
 
+#include "marks.h"
 //#include "text/paragraphlayout.h"
 #include "text/frect.h"
 #include "text/specialchars.h"
@@ -132,6 +133,8 @@
 	void insertObject(int obj);
 	// Insert object at specific position
 	void insertObject(int pos, int obj);
+	// Insert mark at cursor or specific position
+	void insertMark(Mark* Mark, int pos = -1);
  	void replaceChar(int pos, QChar ch);
  	// Replaced a word, and return the difference in length between old and new
 	int replaceWord(int pos, QString newWord);
@@ -161,6 +164,8 @@
 
 	bool hasObject(int pos) const;
  	PageItem* object(int pos) const;
+	bool hasMark(int pos) const;
+	Mark *mark(int pos) const;
 	
 	int nextCharPos(int c);
 	int prevCharPos(int c);

Modified: trunk/Scribus/scribus/ui/charselect.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/ui/charselect.cpp
==============================================================================
--- trunk/Scribus/scribus/ui/charselect.cpp (original)
+++ trunk/Scribus/scribus/ui/charselect.cpp Sat Oct 27 15:56:36 2012
@@ -103,7 +103,7 @@
 		cItem = m_Item->asTextFrame();
 	if (cItem->HasSel)
 		cItem->deleteSelectedTextFromFrame();
-	cItem->invalidateLayout();
+	cItem->invalidateLayout(false);
 	//CB: Avox please make text->insertchar(char) so none of this happens in gui code, and item can tell doc its changed so the view and mainwindow slotdocch are not necessary
 	QChar ch;
 	QString fontName = m_doc->currentStyle.charStyle().font().scName();
@@ -138,7 +138,7 @@
 		cItem = m_Item->asTextFrame();
 	if (cItem->HasSel)
 		cItem->deleteSelectedTextFromFrame();
-	cItem->invalidateLayout();
+	cItem->invalidateLayout(false);
 // 	//CB: Avox please make text->insertchar(char) so none of this happens in gui code, and item can tell doc its changed so the view and mainwindow slotdocch are not necessary
 	if (ch == QChar(10))
 		ch = QChar(13);

Modified: trunk/Scribus/scribus/ui/checkDocument.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/ui/checkDocument.cpp
==============================================================================
--- trunk/Scribus/scribus/ui/checkDocument.cpp (original)
+++ trunk/Scribus/scribus/ui/checkDocument.cpp Sat Oct 27 15:56:36 2012
@@ -313,7 +313,9 @@
 
 	if ((doc->docItemErrors.count() == 0)
 		 && (doc->masterItemErrors.count() == 0)
-		 && (doc->docLayerErrors.count() == 0))
+		 && (doc->docLayerErrors.count() == 0)
+	    //this flag is used by documentchecker as indicator for marks change after updating
+		&& !doc->notesChanged())
 	{
 		QTreeWidgetItem * documentItem = new QTreeWidgetItem( reportDisplay );
 		documentItem->setText(COLUMN_ITEM, tr( "Document" ) );
@@ -329,6 +331,16 @@
 		bool layoutGraveError = false;
 		itemError = false;
 // 		QTreeWidgetItem * pagep = 0;
+
+		// MARKS ***********************************************
+		if (doc->notesChanged())
+		{
+			QTreeWidgetItem * marksItem = new QTreeWidgetItem(reportDisplay);
+			marksItem->setText(0, tr("After Marks update document was changed"));
+			marksItem->setIcon(COLUMN_ITEM, onlyWarning );
+			doc->setNotesChanged(false);
+		}
+
 		// LAYERS **********************************************8
 		QTreeWidgetItem * layerItem = new QTreeWidgetItem(reportDisplay);
 		layerItem->setText(COLUMN_ITEM, tr("Layers"));

Modified: trunk/Scribus/scribus/ui/contextmenu.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/ui/contextmenu.cpp
==============================================================================
--- trunk/Scribus/scribus/ui/contextmenu.cpp (original)
+++ trunk/Scribus/scribus/ui/contextmenu.cpp Sat Oct 27 15:56:36 2012
@@ -24,6 +24,7 @@
 
 #include "contextmenu.h"
 #include "prefsmanager.h"
+#include "pageitem_textframe.h"
 #include "scmimedata.h"
 #include "scraction.h"
 #include "scrapbookpalette.h"
@@ -94,6 +95,7 @@
 	QMenu *menuLayer = new QMenu(this);
 	QMenu *menuLevel = new QMenu(this);
 	QMenu *menuPDF = new QMenu(this);
+	QMenu *menuMark = new QMenu(this);
 	QMenu *menuResolution = new QMenu(this);
 //	QMenu *menuWeld = new QMenu(this);
 	
@@ -164,6 +166,34 @@
 		{
 			addSeparator();
 			addAction(m_AP->scrActions["editEditRenderSource"]);
+		}
+		if (m_doc->appMode == modeEdit)
+		{
+			//add actions for marks in edit mode
+			addSeparator();
+			QAction *act2 = addMenu(menuMark);
+			act2->setText( ScribusView::tr("Insert Mark"));
+			menuMark->addAction(m_AP->scrActions["insertMarkVariableText"]);
+			if (m_actionList.contains("insertMarkAnchor"))
+			{
+				menuMark->addAction(m_AP->scrActions["insertMarkAnchor"]);
+				menuMark->addAction(m_AP->scrActions["insertMarkItem"]);
+				menuMark->addAction(m_AP->scrActions["insertMark2Mark"]);
+				if (!currItem->isNoteFrame())
+					menuMark->addAction(m_AP->scrActions["insertMarkNote"]);
+				//	menuMark->addAction(m_AP->scrActions["insertMarkIndex"]);
+			}
+			if (currItem->itemText.cursorPosition() < currItem->itemText.length())
+			{
+				ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+				if (hl->hasMark())
+					addAction(m_AP->scrActions["editMark"]);
+			}
+		}
+		if (!m_doc->marksList().isEmpty())
+		{
+			addSeparator();
+			addAction(m_AP->scrActions["itemUpdateMarks"]);
 		}
 		if (m_actionList.contains("fileImportText"))
 		{

Modified: trunk/Scribus/scribus/ui/loremipsum.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/ui/loremipsum.cpp
==============================================================================
--- trunk/Scribus/scribus/ui/loremipsum.cpp (original)
+++ trunk/Scribus/scribus/ui/loremipsum.cpp Sat Oct 27 15:56:36 2012
@@ -282,6 +282,12 @@
 		PageItem* currItem = m_Doc->m_Selection->itemAt(i);
 		if (currItem == NULL)
 			continue;
+		//do not insert lorem ipsum text into notes frames
+		if (currItem->isNoteFrame())
+			continue;
+		//removing marks and notes from current text
+//		if (currItem->isTextFrame() && !currItem->asTextFrame()->removeMarksFromText(!m_Doc->hasGUI()))
+//			continue;
 		PageItem *i2 = currItem;
 		if (m_Doc->appMode == modeEditTable)
 			i2 = currItem->asTable()->activeCell().textFrame();
@@ -346,7 +352,7 @@
 		delete lp;
 		if (m_Doc->docHyphenator->AutoCheck)
 			m_Doc->docHyphenator->slotHyphenate(i2);
-		i2->invalidateLayout();
+		i2->asTextFrame()->invalidateLayout(true);
 	}
 	m_Doc->regionsChanged()->update(QRectF());
 	m_Doc->changed();

Modified: trunk/Scribus/scribus/undomanager.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/undomanager.cpp
==============================================================================
--- trunk/Scribus/scribus/undomanager.cpp (original)
+++ trunk/Scribus/scribus/undomanager.cpp Sat Oct 27 15:56:36 2012
@@ -992,6 +992,15 @@
 	UndoManager::ImportText         = tr("Import text");
 	UndoManager::ClearText          = tr("Clear text");
 	UndoManager::AddLoremIpsum      = tr("Add Lorem Ipsum");
+	UndoManager::InsertMark         = tr("Insert mark");
+	UndoManager::InsertNote         = tr("Insert note");
+	UndoManager::EditMark           = tr("Edit mark");
+	UndoManager::DeleteMark         = tr("Delete mark");
+	UndoManager::DeleteNote         = tr("Delete note");
+	UndoManager::NewNotesStyle      = tr("Add note style");
+	UndoManager::EditNotesStyle     = tr("Edit note style");
+	UndoManager::DeleteNotesStyle   = tr("Delete note style");
+	UndoManager::DeleteNotesStyle   = tr("Delete note style");
 	UndoManager::DeletePage         = tr("Delete page");
 	UndoManager::DeletePages        = tr("Delete pages");
 	UndoManager::ChangePageProps    = tr("Change page properties");
@@ -1256,6 +1265,14 @@
 QString UndoManager::ReplaceText        = "";
 QString UndoManager::InsertText         = "";
 QString UndoManager::AddLoremIpsum      = "";
+QString UndoManager::EditMark           = "";
+QString UndoManager::InsertMark         = "";
+QString UndoManager::DeleteMark         = "";
+QString UndoManager::InsertNote         = "";
+QString UndoManager::DeleteNote         = "";
+QString UndoManager::NewNotesStyle      = "";
+QString UndoManager::EditNotesStyle      = "";
+QString UndoManager::DeleteNotesStyle   = "";
 QString UndoManager::DeletePage         = "";
 QString UndoManager::DeletePages        = "";
 QString UndoManager::ChangePageProps    = "";

Modified: trunk/Scribus/scribus/undomanager.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/undomanager.h
==============================================================================
--- trunk/Scribus/scribus/undomanager.h (original)
+++ trunk/Scribus/scribus/undomanager.h Sat Oct 27 15:56:36 2012
@@ -587,6 +587,14 @@
 	static QString AddLoremIpsum;
 	static QString DeleteText;
 	static QString InsertText;
+	static QString InsertMark;
+	static QString InsertNote;
+	static QString EditMark;
+	static QString DeleteMark;
+	static QString NewNotesStyle;
+	static QString EditNotesStyle;
+	static QString DeleteNotesStyle;
+	static QString DeleteNote;
 	static QString DeletePage;
 	static QString DeletePages;
 	static QString ChangePageProps;

Modified: trunk/Scribus/scribus/undostate.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/undostate.h
==============================================================================
--- trunk/Scribus/scribus/undostate.h (original)
+++ trunk/Scribus/scribus/undostate.h Sat Oct 27 15:56:36 2012
@@ -28,8 +28,10 @@
 #define UNDOSTATE_H
 
 #include <QMap>
+#include <QPair>
 #include <QPixmap>
 #include <QVariant>
+#include <QList>
 
 #include "scribusapi.h"
 #include "undoobject.h"
@@ -295,5 +297,19 @@
 private:
 	C item_;
 };
+/**** ItemsState for list of pointers to items *****/
+//template<class C>
+class ScItemsState : public SimpleState
+{
+public:
+	ScItemsState(const QString& name, const QString& description = 0, QPixmap* pixmap = 0)
+	: SimpleState(name, description, pixmap) {}
+	~ScItemsState() {}
+	void insertItem(QString itemname, void * item) { pointerMap.insert(itemname, item); }
+	void* getItem(QString itemname) const { if (pointerMap.contains(itemname)) return pointerMap.value(itemname); else return NULL;}
+	QList< QPair<void*, int> > insertItemPos;
+private:
+	QMap<QString,void*> pointerMap;
+};
 
 #endif

Modified: trunk/Scribus/scribus/util.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/util.cpp
==============================================================================
--- trunk/Scribus/scribus/util.cpp (original)
+++ trunk/Scribus/scribus/util.cpp Sat Oct 27 15:56:36 2012
@@ -537,7 +537,7 @@
 	return QString("%1-%2%3.%4").arg(defaultName).arg(QObject::tr("page", "page export")).arg(number, 3, 10, QChar('0')).arg(extension);
 }
 
-const QString getStringFromSequence(DocumentSectionType type, uint position)
+const QString getStringFromSequence(DocumentSectionType type, uint position, QString asterix)
 {
 	QString retVal("");
 	switch( type )
@@ -558,6 +558,10 @@
 			//well, for lower case people will want that, even if its "wrong"
 			//ie, X=10, x=10000
 			retVal=arabicToRoman(position).toLower();
+			break;
+		case Type_asterix:
+			for (uint a=1; a <= position; ++a)
+				retVal.append(asterix);
 			break;
 		case Type_None:
 			break;
@@ -1124,3 +1128,19 @@
 	}
 	delete gItem;
 }
+
+void getUniqueName(QString &name, QStringList list, QString separator, bool prepend)
+{
+	if (!list.contains(name))
+		return;
+	int token = -1;
+	QString newName;
+	do {
+		token++;
+		if (prepend)
+			newName = separator + QString::number(token) + " " + name;
+		else
+			newName = name + separator + QString::number(token);
+	} while (list.contains(newName));
+	name = newName;
+}

Modified: trunk/Scribus/scribus/util.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/util.h
==============================================================================
--- trunk/Scribus/scribus/util.h (original)
+++ trunk/Scribus/scribus/util.h Sat Oct 27 15:56:36 2012
@@ -129,7 +129,9 @@
  */
 QString SCRIBUS_API getFileNameByPage(ScribusDoc* currDoc, uint pageNo, QString extension);
 void SCRIBUS_API sDebug(QString message);
-const QString SCRIBUS_API getStringFromSequence(DocumentSectionType type, uint position);
+//asterix is QString used in numeration when number is presented as few chars, like *, **, *** etc
+//default is '*' but can be used any string
+const QString SCRIBUS_API getStringFromSequence(DocumentSectionType type, uint position, QString asterix="*");
 const QString SCRIBUS_API arabicToRoman(uint i);
 const QString SCRIBUS_API numberToLetterSequence(uint i);
 void SCRIBUS_API parsePagesString(QString pages, std::vector<int>* pageNs, int sourcePageCount);
@@ -152,4 +154,10 @@
 void SCRIBUS_API printBacktrace(int nFrames);
 void SCRIBUS_API convertOldTable(ScribusDoc *m_Doc, PageItem* gItem, QList<PageItem*> &gpL, QStack< QList<PageItem*> > *groupStackT = NULL, QList<PageItem *> *target = NULL);
 
+/*!
+ *\brief
+ * check if name exists in list
+ * if exist then seprator and numbers are pre/append to name while it will be unique
+*/
+void SCRIBUS_API getUniqueName(QString &name, QStringList list, QString separator = "", bool prepend = false);
 #endif

Modified: trunk/Scribus/scribus/util_text.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/util_text.cpp
==============================================================================
--- trunk/Scribus/scribus/util_text.cpp (original)
+++ trunk/Scribus/scribus/util_text.cpp Sat Oct 27 15:56:36 2012
@@ -18,6 +18,7 @@
 
 #include "scribusdoc.h"
 #include "util_text.h"
+#include "serializer.h"
 
 int findParagraphStyle(ScribusDoc* doc, const ParagraphStyle& parStyle)
 {
@@ -50,3 +51,18 @@
 	assert(false);
 	return -1;
 }
+
+StoryText desaxeString(ScribusDoc* doc, QString saxedString)
+{
+	assert(!saxedString.isEmpty());
+
+	Serializer* dig = doc->textSerializer();
+	dig->parseMemory(saxedString.toStdString().c_str(), saxedString.length());
+
+	StoryText* story = dig->result<StoryText>();
+	assert (story != NULL);
+
+	StoryText res = *story;
+	delete story;
+	return res;
+}

Modified: trunk/Scribus/scribus/util_text.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17826&path=/trunk/Scribus/scribus/util_text.h
==============================================================================
--- trunk/Scribus/scribus/util_text.h (original)
+++ trunk/Scribus/scribus/util_text.h Sat Oct 27 15:56:36 2012
@@ -13,6 +13,7 @@
 #include "styles/charstyle.h"
 #include "styles/paragraphstyle.h"
 #include "scribusapi.h"
+#include "text/storytext.h"
 
 class  ScribusDoc;
 
@@ -21,5 +22,7 @@
 int SCRIBUS_API findParagraphStyle(ScribusDoc* doc, const QString &name);
 #endif
 
+// returns StoryText from saxed string
+StoryText SCRIBUS_API desaxeString(ScribusDoc* doc, QString saxedString);
 
 #endif




More information about the scribus-commit mailing list