View Issue Details

IDProjectCategoryView StatusLast Update
0010428ScribusUsabilitypublic2012-07-03 10:12
Reportercezaryece Assigned Tocezaryece  
PrioritynormalSeverityfeatureReproducibilityN/A
Status closedResolutionsuspended 
Platformall 
Product Version1.5.0svn 
Summary0010428: [new feature patch] markers feature - dynamic references and variable text
DescriptionMarkers idea is based on inline objects but in that case objects are dynamic text insertions into text wchich are automatically (almost) updated while doc structure is changing.

Marker has its label, type and some data in its structure. Pair label + type is unique, so there is possible to insert different type markers but with same label (dont know - maybe it will be useful for someone).
Variable text marker can be inserted in many places in text, others markers can have only one occurrence in text.
Markers in text are inserted by SpecialChar::OBJECT glyph with pointer to specified marker in its structure (otherwise it must be inline frame or other object).

While formatting text, markers are resolved to proprietary text - page number (calculated as reference to some place in document) or variable text. markers are noticed by small red marks if option for show special chars is on.

Till now patch provides 4 kinds of markers:
1. anchors - they are invisible marks in text pointed in some place of text - other markers can be referenced to these anchors; anchors doesn't provide any text impact in its places.
2. markers to markers - resolving to page number where pointed marker is placed; user can select all markers as reference target but not variable text markers, as these markers can have many occurrences in text
3. markers to items - resolving to page number where pointed item (frame, line) is placed
4. variable text markers - in place of occurrence text stored in marker definition is placed - very useful for often used small parts of same text, which should be often updated, like dates, sections/chapters titles, number of issue, etc.

Creating markers - by command "insert Marker" from menu / contextmenu in text editing mode
Editing markers - by command in menu, by doubleclick on it in text or by Markers Manager.
Deleting marker - while editing text user can delete only marker char in text, but completely removing it from user can by deleting marker in Markers Manager.

Markers Manager is palette with list of all markers used in current doc. User can edit and delete selected marker and force update of references in all document - text items with markers will be updated with current values (although most operations on markers should update references automatically).

ToDo:
- undo/redo
- copy/paste operations for text with markers (for now markers appearance is ignored)
- provided data validation in creating/editing marker dialogbox (now marker is not created or changed if values inserted by user are wrong)

What next:
- foot / endnotes
- indexes
Additional InformationSeems you must apply my patch from trunk/Scribus directory
As usual with my patches - try with "-l" option for avoid problems with white chars difference.
TagsNo tags attached.
Patch

Activities

cezaryece

2011-12-09 14:01

updater  

markers.patch (65,817 bytes)   
Index: scribus/scribusdoc.cpp
===================================================================
--- scribus/scribusdoc.cpp	(wersja 17064)
+++ scribus/scribusdoc.cpp	(kopia robocza)
@@ -100,6 +100,12 @@
 #include "colormgmt/sccolormgmtenginefactory.h"
 #include "ui/hruler.h"
 #include "ui/layers.h"
+#include "ui/MarkerInsertDlg.h"
+#include "ui/marker2item.h"
+#include "ui/marker2marker.h"
+#include "ui/markeranchor.h"
+#include "ui/markervariabletext.h"
+#include "ui/markersmanager.h"
 #include "ui/scmessagebox.h"
 #include "ui/storyeditor.h"
 
@@ -628,6 +634,11 @@
 			delete pa.items.takeFirst();
 		}
 	}
+	QList<Marker*> marks = markersMap.values();
+	for (int i =0; i < marks.count(); ++i)
+		delete marks[i];
+	marks.clear();
+	markersMap.clear();
 	docPatterns.clear();
 	docGradients.clear();
 	while (!DocItems.isEmpty())
@@ -14557,6 +14568,327 @@
 	}
 }
 
+Marker* ScribusDoc::getMarkerDefinied(QString l, MarkerType t)
+{
+	if (markersMap.contains(l))
+	{
+		QList<Marker*> mlist = markersMap.values(l);
+		QList<Marker*>::const_iterator i;
+		for (i = mlist.constBegin(); i != mlist.constEnd(); ++i)
+		{
+			if ((*i)->getType() == t)
+				return (*i);
+		}
+	}
+	return NULL;
+}
+
+PageItem* ScribusDoc::findMarker(Marker* marker, int &lastItem)
+{
+	lastItem++;
+	for (int a = lastItem; a < Items->count(); ++a)
+	{
+		PageItem* currItem = Items->at(a);
+		if (currItem->isTextFrame() && currItem->itemText.length() > 0)
+		{
+			for (int i = currItem->firstInFrame(); i < currItem->itemText.length(); i++)
+			{
+				ScText* hl = currItem->itemText.item(i);
+				if ((hl->ch == SpecialChars::OBJECT) && (hl->marker == marker))
+				{
+					lastItem = a;
+					return currItem;
+				}
+			}
+		}
+	}
+	lastItem = 0;
+	return NULL;
+}
+
+PageItem* ScribusDoc::findMarker(Marker* marker)
+{
+	int temp = -1;
+	return findMarker(marker,temp);
+}
+
+PageItem* ScribusDoc::findMarker(QString label, MarkerType type)
+{
+	return findMarker(getMarkerDefinied(label, type));
+}
+
+bool ScribusDoc::findMarkerCPos(Marker* marker, PageItem* &currItem, int &pos)
+{
+	if (currItem->isTextFrame() && currItem->itemText.length() > 0)
+	{
+		for (pos = currItem->firstInFrame(); pos < currItem->itemText.length(); pos++)
+		{
+			ScText* hl = currItem->itemText.item(pos);
+			if ((hl->ch == SpecialChars::OBJECT) && (hl->marker == marker))
+				return true;
+		}
+	}
+	return false;
+}
+
+bool ScribusDoc::eraseMarker(Marker *marker)
+{
+	bool found = false;
+	QMap<QString, Marker*>::Iterator mIt = markersMap.find(marker->label);
+	//find markers pointed to that marker
+	while (mIt != markersMap.end())
+	{
+		Marker* mrk = (Marker*) mIt.value();
+		if ((mrk->getType()==MARKER2MarkerType) && (mrk->getMarker() == marker))
+			mrk->setMarker(NULL);
+		mIt++;
+	}
+	//find and delete all marker`s apperences in text
+	int MPos;
+	PageItem* item = findMarker(marker);
+	int itemIndex;
+	while (item != NULL)
+	{
+		itemIndex = DocItems.indexOf(item);
+		while (findMarkerCPos(marker, item, MPos))
+		{
+			item->itemText.select(MPos,1);
+			item->asTextFrame()->deleteSelectedTextFromFrame();
+		}
+		found = true;
+		item->update();
+		item = findMarker(marker,itemIndex);
+	}
+	mIt = markersMap.find(marker->label);
+	while (mIt != markersMap.end())
+	{
+		Marker* mrk = (Marker*) mIt.value();
+		if (mrk == marker)
+		{
+			markersMap.erase(mIt);
+			break;
+		}
+		mIt++;
+	}
+	return found;
+}
+
+bool ScribusDoc::eraseMarker(QString label, MarkerType type)
+{
+	return eraseMarker(getMarkerDefinied(label, type));
+}
+
+void ScribusDoc::editMarkerDlg(Marker * marker)
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	QVector<Marker*> markerList;
+	for(markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+		Marker* mark = markIt.value();
+		markerList.push_back(mark);
+	}
+	MarkerInsertDlg* editMDialog = NULL;
+	switch (marker->getType())
+	{
+	case MARKERAnchorType:
+		editMDialog = (MarkerInsertDlg*) new MarkerAnchorDlg(scMW());
+		editMDialog->setValues(marker->label);
+		break;
+	case MARKERVariableTextType:
+		editMDialog = (MarkerInsertDlg*) new MarkerVariableTextDlg(markerList, false, scMW());
+		editMDialog->setValues(marker->label, marker->getString());
+		break;
+	case MARKER2ItemType:
+		editMDialog = (MarkerInsertDlg*) new Marker2ItemDlg(scMW());
+		editMDialog->setValues(marker->label, marker->getItemPtr());
+		break;
+	case MARKER2MarkerType:
+		editMDialog = (MarkerInsertDlg*) new Marker2MarkerDlg(markerList, marker, scMW());
+		editMDialog->setValues(marker->label, marker->getMarker());
+		break;
+	case MARKERFootnoteType:
+		break;
+	case MARKEREndnoteType:
+		break;
+	case MARKERIndexType:
+		break;
+	default:
+		break;
+	}
+	editMDialog->setWindowTitle(tr("Edit ") + editMDialog->windowTitle());
+	if (editMDialog->exec())
+	{
+		Marker* Mrk = NULL;
+		MarkerData d;
+		 d.strPtr = NULL;
+		 d.itemPtr = NULL;
+		 d.mrkPtr = NULL;
+		 d.itemName = "";
+		QString label = "", text = "";
+		QString oldStr = marker->getString();
+		switch (marker->getType())
+		{
+		case MARKERAnchorType:
+			//only gets label for new marker
+			editMDialog->values(label);
+			if (label.isEmpty() || getMarkerDefinied(label, MARKERAnchorType) != NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			marker->label = label;
+			break;
+		case MARKERVariableTextType:
+			Mrk = editMDialog->values(label, text);
+			if (label.isEmpty() || text.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (Mrk != NULL)
+				marker = Mrk;
+			marker->label = label;
+			if (text != oldStr)
+			{
+				marker->setString(text);
+				updateMarkerVariableText(marker, true);
+			}
+			break;
+		case MARKER2ItemType:
+			editMDialog->values(label, d.itemPtr);
+			if (label.isEmpty() || d.itemPtr == NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.itemPtr != marker->getItemPtr())
+			{
+				marker->setItemPtr(d.itemPtr);
+				marker->setString(QString("%1").arg(d.itemPtr->OwnPage +1));
+			}
+			marker->label = label;
+			break;
+		case MARKER2MarkerType:
+			//gets pointer to referenced marker
+			editMDialog->values(label, d.mrkPtr);
+			if ((d.mrkPtr == NULL) && label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.mrkPtr == NULL)
+			{
+				marker->setMarker(d.mrkPtr);
+				marker->setString("");
+			}
+			else if (d.mrkPtr != marker->getMarker())
+			{
+				marker->setMarker(d.mrkPtr);
+				marker->setString(QString("%1").arg(d.mrkPtr->OwnPage +1));
+			}
+			marker->label = label;
+		case MARKERFootnoteType:
+			break;
+		case MARKEREndnoteType:
+			break;
+		case MARKERIndexType:
+			break;
+		default:
+			break;
+		}
+		changed();
+	}
+	delete editMDialog;
+}
+
+void ScribusDoc::updateMarkerVariableText(Marker* marker, bool forceUpdate)
+{
+	if (marker->getType() == MARKERVariableTextType)
+	{
+		int itemNo = -1;
+		PageItem* mItem = findMarker(marker, itemNo);
+		while (mItem != NULL)
+		{
+			if (forceUpdate)
+				mItem->layout();
+			else
+			{
+				mItem->invalidateLayout();
+			}
+			mItem = findMarker(marker, itemNo);
+		}
+	}
+}
+
+void ScribusDoc::updateMarkers() //update strings (page number) for markers pointed to anchors and items
+{
+	if (isLoading())
+		return;
+	QMap<QString,Marker*>::Iterator markIt;
+	//for all markers
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		//set marker page number
+		PageItem* mItem = findMarker(marker);
+		if (mItem != NULL)
+			marker->OwnPage = mItem->OwnPage;
+		else
+			marker->OwnPage = -1;
+	}
+	QList<Marker*> toDeleting;
+	//run for update markers to items
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		if (marker->getType() == MARKER2ItemType)
+		{
+			if (marker->getItemPtr() == NULL)  //pointer to item not set
+			{
+				qWarning() << "Wrong marker [" << marker->label << "] to item data - no item pointer and no item name - DELETING IT";
+				toDeleting.append(marker);
+				continue;
+			}
+			int page = marker->getItemPtr()->OwnPage +1;
+			if (marker->getString().toInt() != page)
+			{
+				marker->setString(QString("%1").arg(page));
+				(findMarker(marker))->invalidateLayout();
+			}
+		}
+	}
+	//run for markers to markers
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+
+		Marker* marker = markIt.value();
+		if (marker->getType() == MARKER2MarkerType)
+		{
+			Marker* destMark = marker->getMarker();
+			if (destMark == NULL)
+			{
+				qWarning() << QString("Update markers2markers: marker %1 - destination marker is NULL").arg(marker->label);
+				toDeleting.append(marker);
+				continue;
+			}
+			PageItem* mItem = findMarker(destMark);
+			if (mItem == NULL)
+			{
+				destMark->OwnPage = -1;
+				marker->setString("");
+			}
+			else
+			{
+				destMark->OwnPage = (findMarker(destMark))->OwnPage;
+				int page = destMark->OwnPage +1;
+				if (marker->getString().toInt() != page)
+				{
+					marker->setString(QString("%1").arg(page));
+					(findMarker(marker))->invalidateLayout();
+				}
+			}
+		}
+	}
+	//run for variable text (invalidate frames with variable text)
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+		updateMarkerVariableText(markIt.value(), false);
+	if (!toDeleting.isEmpty())
+	{
+		for (int i = 0; i < toDeleting.count(); i++)
+			eraseMarker(toDeleting.at(i));
+	}
+	scMW()->slotUpdateMarkers();
+	scMW()->markersManager->updateListView();
+}
+
 void ScribusDoc::itemSelection_UnWeld()
 {
 	PageItem *currItem;
Index: scribus/canvasmode_edit.cpp
===================================================================
--- scribus/canvasmode_edit.cpp	(wersja 17064)
+++ scribus/canvasmode_edit.cpp	(kopia robocza)
@@ -347,6 +347,11 @@
 				currItem->itemText.extendSelection(start, stop);
 				currItem->itemText.setCursorPosition(stop);
 			}
+			else if ((currItem->itemText.cursorPosition() < currItem->itemText.length()) && (currItem->itemText.item(currItem->itemText.cursorPosition())->marker != NULL))
+			{	//invoke edit marker dialog
+				m_ScMW->slotEditMarker();
+				return;
+			}
 			else
 			{	//Double click in a frame to select a word
 				oldCp = currItem->itemText.cursorPosition();
Index: scribus/sctextstruct.h
===================================================================
--- scribus/sctextstruct.h	(wersja 17064)
+++ scribus/sctextstruct.h	(kopia robocza)
@@ -28,6 +28,7 @@
 #include "styles/paragraphstyle.h"
 
 class PageItem;
+class Marker;
 
 /* Struktur fuer Pageitem Text */
 
@@ -116,7 +117,6 @@
 	InlineFrameData* d;
 };
 
-
 #ifndef NLS_PROTO
 class SCRIBUS_API ScText : public CharStyle
 {
@@ -128,16 +128,17 @@
 	float PRot;
 	float PDx;
 	InlineFrame embedded;
+	Marker* marker;
 	QChar ch;
 	ScText() : 
 		CharStyle(),
 		parstyle(NULL), glyph(), 
-		PtransX(0.0f), PtransY(0.0f), PRot(0.0f), PDx(0.0f), embedded(NULL), ch() {}
+		PtransX(0.0f), PtransY(0.0f), PRot(0.0f), PDx(0.0f), embedded(NULL), marker(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), marker(other.marker), ch(other.ch)
 	{
 		glyph.more = NULL;
 		GlyphLayout *layout = &glyph;
Index: scribus/pageitem.h
===================================================================
--- scribus/pageitem.h	(wersja 17064)
+++ scribus/pageitem.h	(kopia robocza)
@@ -237,16 +237,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();
 	void saxx(SaxHandler& handler, const Xml_string& elemtag) const {}
 	void saxx(SaxHandler& handler) const {}
 	
Index: scribus/pageitem.cpp
===================================================================
--- scribus/pageitem.cpp	(wersja 17064)
+++ scribus/pageitem.cpp	(kopia robocza)
@@ -41,6 +41,7 @@
 #include "cmsettings.h"
 #include "colorblind.h"
 #include "commonstrings.h"
+#include "markers.h"
 
 #include "pageitem_textframe.h"
 #include "pageitem_latexframe.h"
@@ -825,6 +826,20 @@
 	isInlineImage = false;
 }
 
+PageItem::~PageItem()
+{
+	if (tempImageFile != NULL)
+		delete tempImageFile;
+	//delete markers pointed to that item
+	QMap<QString,Marker*>::Iterator markIt;
+	for (markIt = doc()->markersMap.begin(); markIt != doc()->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		if ((marker->getType() == MARKER2ItemType) && (marker->getItemPtr() == this))
+			doc()->eraseMarker(marker);
+	}
+}
+
 void PageItem::setXPos(const double newXPos, bool drawingOnly)
 {
 	Xpos = newXPos;
@@ -2204,6 +2219,15 @@
 		else
 			return "%";
 	}
+	//check for markers
+	else if (ch == SpecialChars::OBJECT)
+	{
+		ScText* hl = itemText.item(base);
+		if (hl->marker != NULL && hl->marker->getType() != MARKERAnchorType && hl->marker->getType() != MARKERIndexType)
+		{
+			chstr = hl->marker->getString();
+		}
+	}
 	return chstr;
 }
 
@@ -2387,6 +2411,12 @@
 			points.addQuadPoint(0, -10, 0, -10, 0, -6, 0, -6);
 			stroke = true;
 		}
+		else if (glyph == SpecialChars::OBJECT.unicode())
+		{
+			points.resize(0);
+			points.addQuadPoint(0, -8, 1, -8, 0, -6, 1, -6);
+			stroke = true;
+		}
 		else // ???
 		{
 			points.resize(0);
Index: scribus/scribusdoc.h
===================================================================
--- scribus/scribusdoc.h	(wersja 17064)
+++ scribus/scribusdoc.h	(kopia robocza)
@@ -40,6 +40,7 @@
 #include "scribusapi.h"
 #include "colormgmt/sccolormgmtengine.h"
 #include "documentinformation.h"
+#include "markers.h"
 #include "observable.h"
 #include "pageitem.h"
 #include "pagestructs.h"
@@ -72,7 +73,7 @@
 class ScPattern;
 class UndoTransaction;
 class Serializer;
-
+class MarkersManager;
 class QProgressBar;
 
 struct SCRIBUS_API NodeEditContext : public MassObservable<QPointF>
@@ -1259,7 +1260,7 @@
 	MassObservable<ScPage*> m_pagesChanged;
 	MassObservable<QRectF> m_regionsChanged;
 	DocUpdater* m_docUpdater;
-	
+
 signals:
 	//Lets make our doc talk to our GUI rather than confusing all our normal stuff
 	/**
@@ -1520,8 +1521,24 @@
 	void updatePict(QString name);
 	void updatePictDir(QString name);
 	void removePict(QString name);
-//welding two items
+// Markers
+public:
+	//list of markers with its lables as keys
+	QMap<QString, Marker*> markersMap;
+	Marker* getMarkerDefinied(QString label, MarkerType type); //returns marker with label and type (labels are unique only for same type markers)
+	PageItem* findMarker(Marker* marker, int &lastItem);
+	PageItem* findMarker(Marker* marker);
+	PageItem* findMarker(QString label, MarkerType type);
+	bool findMarkerCPos(Marker* marker, PageItem* &item, int &CPos);
+	bool eraseMarker(QString label, MarkerType type);
+	bool eraseMarker(Marker* marker);
+	void editMarkerDlg(Marker*);
+	void updateMarkerVariableText(Marker* marker, bool forceUpdate = false); //returns if any text was changed
 public slots:
+	void updateMarkers(); //update strings (page number) for markers pointed to anchors and items
+
+	//welding two items
+public slots:
 	void itemSelection_UnWeld();
 	void itemSelection_Weld();
 	void itemSelection_EditWeld();
Index: scribus/actionmanager.cpp
===================================================================
--- scribus/actionmanager.cpp	(wersja 17064)
+++ scribus/actionmanager.cpp	(kopia robocza)
@@ -240,8 +240,11 @@
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 	name="editJavascripts";
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	name="editMarkers";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 
 	(*scrActions)["editStyles"]->setToggleAction(true);
+	(*scrActions)["editMarkers"]->setToggleAction(true);
 
 	connect( (*scrActions)["editUndoAction"], SIGNAL(triggeredData(int)) , undoManager, SLOT(undo(int)) );
 	connect( (*scrActions)["editRedoAction"], SIGNAL(triggeredData(int)) , undoManager, SLOT(redo(int)) );
@@ -540,10 +543,45 @@
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 	(*scrActions)["stickyTools"]->setToggleAction(true);
 
+	//Markers
+	name="insertMarkerAnchor";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarkerVariableText";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarkerItem";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarker2Marker";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+//	name="insertMarkerFootnote";
+//	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+//	(*scrActions)[name]->setEnabled(true);
+//	name="insertMarkerEndnote";
+//	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+//	(*scrActions)[name]->setEnabled(true);
+//	name="insertMarkerIndex";
+//	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+//	(*scrActions)[name]->setEnabled(true);
+	name="editMarker";
+	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)["insertMarkerAnchor"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerAnchor()) );
+	connect( (*scrActions)["insertMarkerVariableText"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerVariableText()) );
+	connect( (*scrActions)["insertMarkerItem"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerItem()) );
+	connect( (*scrActions)["insertMarker2Marker"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarker2Marker()) );
+//	connect( (*scrActions)["insertMarkerFootnote"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerFootnote()) );
+//	connect( (*scrActions)["insertMarkerEndnote"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerEndnote()) );
+//	connect( (*scrActions)["insertMarkerIndex"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerIndex()) );
+	connect( (*scrActions)["editMarker"], SIGNAL(triggered()), mainWindow, SLOT(slotEditMarker()) );
 }
 
 void ActionManager::initPageMenuActions()
@@ -1391,6 +1429,7 @@
 //	(*scrActions)["editPatterns"]->setTexts( tr("Patterns..."));
 //	(*scrActions)["editGradients"]->setTexts( tr("Gradients..."));
 	(*scrActions)["editStyles"]->setTexts( tr("S&tyles..."));
+	(*scrActions)["editMarkers"]->setTexts( tr("Markers..."));
 	(*scrActions)["editMasterPages"]->setTexts( tr("&Master Pages..."));
 	(*scrActions)["editJavascripts"]->setTexts( tr("&JavaScripts..."));
 
@@ -1485,6 +1524,14 @@
 	(*scrActions)["insertGlyph"]->setTexts( tr("&Glyph..."));
 	(*scrActions)["insertSampleText"]->setTexts( tr("Sample Text"));
 	(*scrActions)["stickyTools"]->setTexts( tr("Sticky Tools"));
+	(*scrActions)["insertMarkerAnchor"]->setTexts( tr("Anchor Marker"));
+	(*scrActions)["insertMarkerVariableText"]->setTexts( tr("Variable Text"));
+	(*scrActions)["insertMarkerItem"]->setTexts( tr("Reference to Item"));
+	(*scrActions)["insertMarker2Marker"]->setTexts( tr("Reference to Anchor Marker"));
+//	(*scrActions)["insertMarkerFootnote"]->setTexts( tr("Footnote"));
+//	(*scrActions)["insertMarkerEndnote"]->setTexts( tr("Endnote"));
+//	(*scrActions)["insertMarkerIndex"]->setTexts( tr("Index entry"));
+	(*scrActions)["editMarker"]->setTexts( tr("Edit Marker"));
 
 	//Page menu
 	(*scrActions)["pageInsert"]->setTexts( tr("&Insert..."));
@@ -1873,6 +1920,7 @@
 		<< "editReplaceColors"
 //		<< "editPatterns"
 		<< "editStyles"
+		<< "editMarkers"
 		<< "editMasterPages"
 		<< "editJavascripts";
 	//Style
@@ -1978,7 +2026,15 @@
 		<< "toolsInsertRenderFrame"
 		<< "stickyTools"
 		<< "insertGlyph"
-		<< "insertSampleText";
+		<< "insertSampleText"
+		<< "insertMarkerAnchor"
+		<< "insertMarkerVariableText"
+		<< "insertMarkerItem"
+		<< "insertMarker2Marker"
+//		<< "insertMarkerFootnote"
+//		<< "insertMarkerEndnote"
+//		<< "insertMarkerIndex"
+		<< "editMarker";
 
 	itmenu->second
 		<< "unicodeSoftHyphen"
Index: scribus/pageitem_textframe.cpp
===================================================================
--- scribus/pageitem_textframe.cpp	(wersja 17064)
+++ scribus/pageitem_textframe.cpp	(kopia robocza)
@@ -34,7 +34,9 @@
 
 #include "canvas.h"
 #include "commonstrings.h"
+#include "fonts/scface.h"
 #include "hyphenator.h"
+#include "markers.h"
 #include "pageitem.h"
 #include "pageitem_group.h"
 #include "pageitem_textframe.h"
@@ -53,6 +55,12 @@
 #include "util.h"
 #include "util_math.h"
 
+#include "ui/MarkerInsertDlg.h"
+#include "ui/marker2item.h"
+#include "ui/marker2marker.h"
+#include "ui/markeranchor.h"
+#include "ui/markervariabletext.h"
+#include "ui/markersmanager.h"
 #include "ui/guidemanager.h"
 
 #include <cairo.h>
@@ -1397,6 +1405,15 @@
 		for (int a = firstInFrame(); a < itemText.length(); ++a)
 		{
 			hl = itemText.item(a);
+			if (hl->ch == SpecialChars::OBJECT && hl->marker != NULL)
+			{
+				hl->glyph.glyph = SpecialChars::OBJECT.unicode() + ScFace::CONTROL_GLYPHS;
+				if (hl->marker->getType() == MARKERAnchorType || hl->marker->getType() == MARKERIndexType)
+				{
+					hl->glyph.shrink();
+					continue;
+				}
+			}
 			if (a > 0 && itemText.text(a-1) == SpecialChars::PARSEP)
 				style = itemText.paragraphStyle(a);
 			if (current.itemsInLine == 0)
@@ -1528,8 +1545,12 @@
 				// 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 = charStyle.font().realCharHeight(chstr[0], 1);
-				double realCharAscent = charStyle.font().realCharAscent(chstr[0], 1);
+				double realCharHeight = 0.0, realCharAscent = 0.0;
+				for (int i = 0; i < chstr.length(); i++)
+				{
+					realCharHeight = qMax(realCharHeight, charStyle.font().realCharHeight(chstr[i], 1));
+					realCharAscent = qMax(realCharAscent, charStyle.font().realCharAscent(chstr[i], 1));
+				}
 				double fontAscent     = charStyle.font().ascent(style.charStyle().fontSize() / 10.0);
 				if (realCharHeight == 0.0)
 					realCharHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
@@ -1594,11 +1615,19 @@
 				}
 				else
 				{
-					double realCharHeight = charStyle.font().realCharHeight(chstr[0], charStyle.fontSize() / 10.0);
+					double realCharHeight = 0.0;
+					wide = 0.0; realAsce = 0.0;
+					//
+					for (int i = 0; i < chstr.length(); i++)
+					{
+						realCharHeight = qMax(realCharHeight, charStyle.font().realCharHeight(chstr[i], charStyle.fontSize() / 10.0));
+						realAsce = qMax(realAsce, charStyle.font().realCharHeight(chstr[i], chsd / 10.0));
+						wide += charStyle.font().realCharWidth(chstr[i], chsd / 10.0);
+					}
+					wide = (wide* scaleH) + (1 - scaleH);
+					realAsce = realAsce  * scaleV + offset;
 					if (realCharHeight == 0)
 						realCharHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
-					wide = (charStyle.font().realCharWidth(chstr[0], chsd / 10.0) * scaleH) + (1 - scaleH); //dropcaps are to close to next glyphs if glyphs are hard scaled
-					realAsce = charStyle.font().realCharHeight(chstr[0], chsd / 10.0) * scaleV + offset;
 					asce = charStyle.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;
@@ -1622,12 +1651,19 @@
 					desc = realDesc = 0;
 				else
 				{
+					for (int i = 0; i < chstr.length(); i++)
+					{
+						if (chstr[i] == SpecialChars::OBJECT)
+							continue;
+						realDesc = qMax(realDesc, charStyle.font().realCharDescent(chstr[i], hlcsize10));
+						realAsce = charStyle.font().realCharAscent(chstr[i], hlcsize10);
+					}
+					realDesc =  realDesc * scaleV - offset;
 					desc = -charStyle.font().descent(hlcsize10);
-					realDesc = charStyle.font().realCharDescent(chstr[0], hlcsize10) * scaleV - offset;
 					current.rememberShrinkStretch(hl->ch, wide, style);
 				}
 				asce = charStyle.font().ascent(hlcsize10);
-				realAsce = charStyle.font().realCharAscent(chstr[0], hlcsize10) * scaleV + offset;
+				realAsce = realAsce * scaleV + offset;
 			}
 
 			//check for Y position at beginning of line
@@ -1934,7 +1970,12 @@
 			
 			// remember y pos
 			if (DropCmode)
-				hl->glyph.yoffset -= charStyle.font().realCharHeight(chstr[0], chsd / 10.0) - charStyle.font().realCharAscent(chstr[0], chsd / 10.0);
+			{
+				double yoffset = 0.0;
+				for (int i = 0; i < chstr.length(); i++)
+					yoffset = qMax(yoffset, charStyle.font().realCharHeight(chstr[i], chsd / 10.0) - charStyle.font().realCharAscent(chstr[i], chsd / 10.0));
+				hl->glyph.yoffset -= yoffset;
+			}
 			
 			// remember x pos
 			double breakPos = current.xPos;
@@ -2766,11 +2807,13 @@
 			{
 				bool selecteds = itemText.selected(as);
 				hls = itemText.item(as);
+				if (hls->marker != NULL && (hls->marker->getType() == MARKERAnchorType || hls->marker->getType() == MARKERIndexType))
+					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()) && (hls->ch == SpecialChars::OBJECT && hls->embedded.hasItem()))
 					    || previousWasObject)
 					{
 						sFList << selectedFrame;
@@ -2787,7 +2830,7 @@
 							asce = charStyleS.font().ascent(charStyleS.fontSize() / 10.0);
 							wide = hls->glyph.wide();
 							QRectF scr;
-							if ((hls->ch == SpecialChars::OBJECT)  && (hls->embedded.hasItem()))
+							if (hls->ch == SpecialChars::OBJECT && hls->embedded.hasItem())
 							{
 								double ww = (hls->embedded.getItem()->gWidth + hls->embedded.getItem()->lineWidth()) * hls->glyph.scaleH;
 								double hh = (hls->embedded.getItem()->gHeight + hls->embedded.getItem()->lineWidth()) * hls->glyph.scaleV;
@@ -4026,3 +4069,231 @@
 {
 	invalidateLayout();
 }
+
+void PageItem_TextFrame::insertMarkerDlg(MarkerType markerType)
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	QVector<Marker*> markerList;
+	for (markIt = m_Doc->markersMap.begin(); markIt != m_Doc->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		markerList.push_back(marker);
+	}
+	MarkerInsertDlg* insertMDialog = NULL;
+	switch (markerType)
+	{
+	case MARKERAnchorType:
+		insertMDialog = (MarkerInsertDlg*) new MarkerAnchorDlg(m_Doc->scMW());
+		break;
+	case MARKERVariableTextType:
+		insertMDialog = (MarkerInsertDlg*) new MarkerVariableTextDlg(markerList, true, m_Doc->scMW());
+		break;
+	case MARKER2ItemType:
+		insertMDialog = (MarkerInsertDlg*) new Marker2ItemDlg(m_Doc->scMW());
+		break;
+	case MARKER2MarkerType:
+		insertMDialog = (MarkerInsertDlg*) new Marker2MarkerDlg(markerList, NULL, m_Doc->scMW());
+		break;
+	case MARKERFootnoteType:
+		break;
+	case MARKEREndnoteType:
+		break;
+	case MARKERIndexType:
+		break;
+	}
+	if (insertMDialog == NULL)
+	{
+		qDebug() << "Dialog not implemented for markers type " << markerType;
+		return;
+	}
+	insertMDialog->setWindowTitle(tr("Insert new ") + insertMDialog->windowTitle());
+	if (insertMDialog->exec())
+	{
+		Marker* Mrk = NULL;
+		MarkerData d;
+		 d.strPtr = NULL;
+		 d.itemPtr = NULL;
+		 d.mrkPtr = NULL;
+		QString label = "", text = "";
+		switch (markerType)
+		{
+		case MARKERAnchorType:
+			//only gets label for new marker
+			insertMDialog->values(label);
+			if (label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.itemPtr = this;
+			break;
+		case MARKERVariableTextType:
+			Mrk = insertMDialog->values(label, text);
+			if ((Mrk == NULL) && (label.isEmpty() || text.isEmpty()))
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.strPtr = new QString(text);
+			break;
+		case MARKER2ItemType:
+			insertMDialog->values(label, d.itemPtr);
+			if (d.itemPtr == NULL || label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.strPtr = new QString(QString::number(d.itemPtr->OwnPage +1));
+			break;
+		case MARKER2MarkerType:
+			//gets pointer to referenced marker
+			insertMDialog->values(label, d.mrkPtr);
+			if (d.mrkPtr == NULL || label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.strPtr = new QString(QString::number(d.mrkPtr->OwnPage +1));
+		case MARKERFootnoteType:
+			break;
+		case MARKEREndnoteType:
+			break;
+		case MARKERIndexType:
+			break;
+		}
+		//check if marker with such label exist already
+		if (markerType != MARKERVariableTextType && m_Doc->getMarkerDefinied(label, markerType) != NULL)
+			return; //FIX ME here user should be warned that inserting of marker fails and why
+
+		if (Mrk == NULL)
+		{
+			Mrk = new Marker;
+			Mrk->setValues(label, OwnPage, markerType, d);
+			m_Doc->markersMap.insert(label,Mrk);
+		}
+		else
+		{ // that must be variable text marker
+			Mrk->setStrPtr(d.strPtr);
+			m_Doc->updateMarkerVariableText(Mrk, true);
+		}
+		itemText.insertMarker(Mrk);
+		Mrk->OwnPage = OwnPage;
+		update();
+		m_Doc->changed();
+	}
+	delete insertMDialog;
+	m_Doc->scMW()->markersManager->updateListView();
+}
+
+void PageItem_TextFrame::editMarkerDlg(Marker * marker)
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	QVector<Marker*> markerList;
+	for(markIt = m_Doc->markersMap.begin(); markIt != m_Doc->markersMap.end(); ++markIt)
+	{
+		Marker* mark = markIt.value();
+		markerList.push_back(mark);
+	}
+	MarkerInsertDlg* editMDialog = NULL;
+	switch (marker->getType())
+	{
+	case MARKERAnchorType:
+		editMDialog = (MarkerInsertDlg*) new MarkerAnchorDlg(m_Doc->scMW());
+		editMDialog->setValues(marker->label);
+		break;
+	case MARKERVariableTextType:
+		editMDialog = (MarkerInsertDlg*) new MarkerVariableTextDlg(markerList, true, m_Doc->scMW());
+		editMDialog->setValues(marker->label, marker->getString());
+		break;
+	case MARKER2ItemType:
+		editMDialog = (MarkerInsertDlg*) new Marker2ItemDlg(m_Doc->scMW());
+		editMDialog->setValues(marker->label, marker->getItemPtr());
+		break;
+	case MARKER2MarkerType:
+		editMDialog = (MarkerInsertDlg*) new Marker2MarkerDlg(markerList, marker, m_Doc->scMW());
+		editMDialog->setValues(marker->label, marker->getMarker());
+		break;
+	case MARKERFootnoteType:
+		break;
+	case MARKEREndnoteType:
+		break;
+	case MARKERIndexType:
+		break;
+	default:
+		break;
+	}
+	editMDialog->setWindowTitle(tr("Edit ") + editMDialog->windowTitle());
+	if (editMDialog->exec())
+	{
+		Marker* Mrk = NULL;
+		MarkerData d;
+		 d.strPtr = NULL;
+		 d.itemPtr = NULL;
+		 d.mrkPtr = NULL;
+		 d.itemName = "";
+		QString label = "", text = "";
+		QString oldStr = marker->getString();
+		switch (marker->getType())
+		{
+		case MARKERAnchorType:
+			//only gets label for new marker
+			editMDialog->values(label);
+			if (label.isEmpty() || m_Doc->getMarkerDefinied(label, MARKERAnchorType) != NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			marker->label = label;
+			break;
+		case MARKERVariableTextType:
+			Mrk = editMDialog->values(label, text);
+			if ((Mrk == NULL) && (label.isEmpty() || text.isEmpty()))
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (Mrk != NULL)
+			{
+				if (Mrk != marker)
+				{
+					ScText* hl = itemText.item(itemText.cursorPosition());
+					hl->marker = Mrk;
+					marker = Mrk;
+				}
+				marker->label = label;
+				if (text != oldStr)
+				{
+					marker->setString(text);
+					if (marker->getString() != oldStr)
+						m_Doc->updateMarkerVariableText(marker, true);
+				}
+			}
+			else
+			{
+				d.strPtr = new QString(text);
+				Mrk = new Marker;
+				Mrk->setValues(label, OwnPage, MARKERVariableTextType, d);
+				m_Doc->markersMap.insert(label,Mrk);
+				ScText* hl = itemText.item(itemText.cursorPosition());
+				hl->marker = Mrk;
+			}
+			break;
+		case MARKER2ItemType:
+			editMDialog->values(label, d.itemPtr);
+			if (label.isEmpty() || d.itemPtr == NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.itemPtr != marker->getItemPtr())
+			{
+				marker->setItemPtr(d.itemPtr);
+				marker->setString(QString("%1").arg(d.itemPtr->OwnPage +1));
+			}
+			marker->label = label;
+			break;
+		case MARKER2MarkerType:
+			//gets pointer to referenced marker
+			editMDialog->values(label, d.mrkPtr);
+			if ((d.mrkPtr == NULL) && label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.mrkPtr != marker->getMarker())
+			{
+				marker->setMarker(d.mrkPtr);
+				marker->setString(QString("%1").arg(d.mrkPtr->OwnPage +1));
+			}
+			marker->label = label;
+		case MARKERFootnoteType:
+			break;
+		case MARKEREndnoteType:
+			break;
+		case MARKERIndexType:
+			break;
+		default:
+			break;
+		}
+		update();
+		m_Doc->changed();
+		m_Doc->scMW()->markersManager->updateListView();
+	}
+	delete editMDialog;
+}
Index: scribus/ui/contextmenu.cpp
===================================================================
--- scribus/ui/contextmenu.cpp	(wersja 17064)
+++ scribus/ui/contextmenu.cpp	(kopia robocza)
@@ -94,6 +94,7 @@
 	QMenu *menuLayer = new QMenu(this);
 	QMenu *menuLevel = new QMenu(this);
 	QMenu *menuPDF = new QMenu(this);
+	QMenu *menuMarker = new QMenu(this);
 	QMenu *menuResolution = new QMenu(this);
 	QMenu *menuWeld = new QMenu(this);
 	
@@ -172,6 +173,25 @@
 			addAction(m_AP->scrActions["fileImportAppendText"]);
 			addAction(m_AP->scrActions["toolsEditWithStoryEditor"]);
 			addAction(m_AP->scrActions["insertSampleText"]);
+			if (m_doc->appMode == modeEdit)
+			{
+				QAction *act2 = addMenu(menuMarker);
+				act2->setText( ScribusView::tr("Insert Marker"));
+				menuMarker->addAction(m_AP->scrActions["insertMarkerAnchor"]);
+				menuMarker->addAction(m_AP->scrActions["insertMarkerVariableText"]);
+				menuMarker->addAction(m_AP->scrActions["insertMarkerItem"]);
+				menuMarker->addAction(m_AP->scrActions["insertMarker2Marker"]);
+//				menuMarker->addAction(m_AP->scrActions["insertMarkerFootnote"]);
+//				menuMarker->addAction(m_AP->scrActions["insertMarkerEndnote"]);
+//				menuMarker->addAction(m_AP->scrActions["insertMarkerIndex"]);
+				if (currItem->itemText.cursorPosition() < currItem->itemText.length())
+				{
+					ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+					if (hl->ch == SpecialChars::OBJECT && hl->marker != NULL)
+						addAction(m_AP->scrActions["editMarker"]);
+				}
+
+			}
 		}
 		else //enable this for, eg, text on a path
 			if (m_actionList.contains("toolsEditWithStoryEditor"))
Index: scribus/text/storytext.cpp
===================================================================
--- scribus/text/storytext.cpp	(wersja 17064)
+++ scribus/text/storytext.cpp	(kopia robocza)
@@ -329,10 +329,13 @@
 		if ((it->ch == SpecialChars::PARSEP)) {
 			removeParSep(i);
 		}
+		Marker* mrk = it->marker;
 //		qDebug("remove char %d at %d", (int) it->ch.unicode(), i);
 		d->takeAt(i);
 		d->len--;
 		delete it;
+		if ((mrk != NULL) && mrk->isUnique())
+			doc->eraseMarker(mrk);
 		// #9592 : adjust selFirst and selLast, those values have to be
 		// consistent in functions such as select()
 		if (i <= selLast) --selLast;
@@ -477,6 +480,15 @@
 	invalidate(pos, pos + 1);
 }
 
+void StoryText::insertMarker(Marker* M, int pos)
+{
+	if (pos < 0)
+		pos = d->cursorPosition;
+
+	insertChars(pos, SpecialChars::OBJECT);
+	const_cast<StoryText *>(this)->d->at(pos)->marker = M;
+}
+
 void StoryText::hyphenateWord(int pos, uint len, char* hyphens)
 {
 	assert(pos >= 0);
Index: scribus/text/storytext.h
===================================================================
--- scribus/text/storytext.h	(wersja 17064)
+++ scribus/text/storytext.h	(kopia robocza)
@@ -126,6 +126,8 @@
 	// Insert object at specific position
  	void insertObject(int pos, PageItem* obj);
  	void replaceChar(int pos, QChar ch);
+	// Insert marker at cursor or specific position
+	void insertMarker(Marker* M, int pos = -1);
 
 	void hyphenateWord(int pos, uint len, char* hyphens);
 	
Index: scribus/markers.h
===================================================================
--- scribus/markers.h	(wersja 0)
+++ scribus/markers.h	(wersja 0)
@@ -0,0 +1,77 @@
+#ifndef MARKERS_H
+#define MARKERS_H
+
+#include <QString>
+#include "scribusapi.h"
+class Marker;
+class PageItem;
+
+enum MarkerType
+{
+	MARKERNoType = -1, //undefinied marker type (wrong situation!)
+	MARKERAnchorType = 0, //empty anchor marker, useful for creating references to it
+	MARKER2ItemType = 1, //reference to page item ID
+	MARKER2MarkerType = 2, //reference other marker
+	MARKERVariableTextType = 3,//marker contain dynamic text
+	MARKERFootnoteType = 4,  //marker contain footnote
+	MARKEREndnoteType = 5,  //marker contain endnote
+	MARKERIndexType = 6 // index entry
+};
+
+struct MarkerData
+{
+	PageItem* itemPtr;
+	QString* strPtr;
+	Marker* mrkPtr;
+	QString itemName;
+};
+
+class SCRIBUS_API Marker
+{
+public:
+	QString label;
+	int OwnPage;
+	Marker() { label = "", OwnPage = -1, typ = MARKERNoType, data.itemPtr = NULL; data.strPtr = NULL; data.mrkPtr = NULL; }
+	Marker(const Marker& other) : label(other.label), OwnPage(other.OwnPage), typ(other.typ), data(other.data) {}
+	~Marker()
+	{
+		if (data.strPtr != NULL)
+			delete data.strPtr;
+	}
+	void setValues(QString l, int p, MarkerType t, MarkerData d) { label = l; OwnPage = p; typ = t; data = d; }
+	MarkerType getType() { return typ; }
+	void setType(MarkerType t) { typ = t; }
+	MarkerData getData() { return data; }
+	void setData(MarkerData d) { data = d; }
+	PageItem* getItemPtr() { return data.itemPtr; }
+	void setItemPtr( PageItem* ptr ) { data.itemPtr = ptr; }
+	QString getItemName() { return data.itemName; }
+	void setItemName( QString name ) { data.itemName = name; }
+	QString* getStrPtr() { return data.strPtr; }
+	QString getString()
+	{
+		if (data.strPtr != NULL)
+			return *data.strPtr;
+		else
+			return "";
+	}
+	void setMarker(Marker* mP) { data.mrkPtr = mP; }
+	Marker* getMarker() { return data.mrkPtr; }
+	void setStrPtr( QString* p ) { data.strPtr = p; }
+	void setString( QString str )
+	{
+		if (data.strPtr != NULL)
+			delete data.strPtr;
+		data.strPtr = new QString(str);
+	}
+
+	bool hasItemPtr() { return data.itemPtr != NULL; }
+	bool hasString() { return data.strPtr != NULL; }
+	bool hasMarker() { return data.mrkPtr != NULL; }
+	bool isUnique() { return (typ==MARKERAnchorType || typ==MARKERFootnoteType || typ==MARKEREndnoteType); }
+private:
+	MarkerType typ;
+	MarkerData data;
+};
+
+#endif // MARKERS_H
Index: scribus/scribus.cpp
===================================================================
--- scribus/scribus.cpp	(wersja 17064)
+++ scribus/scribus.cpp	(kopia robocza)
@@ -99,6 +99,7 @@
 #include "gtgettext.h"
 #include "hyphenator.h"
 #include "langmgr.h"
+#include "markers.h"
 #include "pageitem_group.h"
 #include "pageitem_imageframe.h"
 #include "pageitem_latexframe.h"
@@ -163,6 +164,8 @@
 #include "ui/loremipsum.h"
 #include "ui/marginwidget.h"
 #include "ui/margindialog.h"
+#include "ui/MarkerInsertDlg.h"
+#include "ui/markersmanager.h"
 #include "ui/masterpagepalette.h"
 #include "ui/mergedoc.h"
 #include "ui/movepage.h"
@@ -582,6 +585,12 @@
 	connect( styleManager, SIGNAL(paletteShown(bool)), scrActions["editStyles"], SLOT(setChecked(bool)));
 	styleManager->installEventFilter(this);
 
+	// initializing marker`s manager
+	markersManager = new MarkersManager(this, "markersManager");
+	connect( scrActions["editMarkers"], SIGNAL(toggled(bool)), markersManager, SLOT(setPaletteShown(bool)) );
+	connect( markersManager, SIGNAL(paletteShown(bool)), scrActions["editMarkers"], SLOT(setChecked(bool)));
+	markersManager->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)));
@@ -721,6 +730,7 @@
 //	scrMenuMgr->addMenuItem(scrActions["editGradients"], "Edit", false);
 //	scrMenuMgr->addMenuItem(scrActions["editPatterns"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editStyles"], "Edit", false);
+	scrMenuMgr->addMenuItem(scrActions["editMarkers"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editMasterPages"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editJavascripts"], "Edit", false);
 	scrMenuMgr->setMenuEnabled("EditPasteRecent", false);
@@ -837,6 +847,8 @@
 	scrMenuMgr->addMenuItem(scrActions["itemWeld"], "Item", false);
 	scrMenuMgr->addMenuItem(scrActions["itemEditWeld"], "Item", false);
 
+	scrMenuMgr->addMenuItem(scrActions["editMarker"], "Item", false);
+
 	//Insert menu
 	scrMenuMgr->createMenu("Insert", ActionManager::defaultMenuNameEntryTranslated("Insert"));
 	scrMenuMgr->addMenuItem(scrActions["insertFrame"], "Insert", false);
@@ -927,6 +939,15 @@
 
 	scrMenuMgr->addMenuSeparator("Insert");
 	scrMenuMgr->addMenuItem(scrActions["insertSampleText"], "Insert", false);
+	scrMenuMgr->addMenuSeparator("Insert");
+	scrMenuMgr->createMenu("InsertMarker", tr("Markers"), "Insert");
+	scrMenuMgr->addMenuItem(scrActions["insertMarkerAnchor"], "InsertMarker", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarkerVariableText"], "InsertMarker", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarkerItem"], "InsertMarker", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarker2Marker"], "InsertMarker", false);
+//	scrMenuMgr->addMenuItem(scrActions["insertMarkerFootnote"], "InsertMarker", false);
+//	scrMenuMgr->addMenuItem(scrActions["insertMarkerEndnote"], "InsertMarker", false);
+//	scrMenuMgr->addMenuItem(scrActions["insertMarkerIndex"], "InsertMarker", false);
 
 	//Page menu
 	scrMenuMgr->createMenu("Page", ActionManager::defaultMenuNameEntryTranslated("Page"));
@@ -1129,6 +1150,7 @@
 //AV to be replaced with Selection::update and listener in PropertiesPalette
 void ScribusMainWindow::setTBvals(PageItem *currItem)
 {
+	scrActions["editMarker"]->setEnabled(false);
 	if (currItem->itemText.length() != 0)
 	{
 //		int ChPos = qMin(currItem->CPos, static_cast<int>(currItem->itemText.length()-1));
@@ -1142,6 +1164,11 @@
 		emit TextStyle(doc->currentStyle);
 		// to go: (av)
 		propertiesPalette->textPal->updateStyle(doc->currentStyle);
+		if (doc->appMode == modeEdit && currItem->itemText.cursorPosition() < currItem->itemText.length())
+		{
+			ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+			scrActions["editMarker"]->setEnabled((hl->ch == SpecialChars::OBJECT && hl->marker != NULL));
+		}
 	}
 }
 
@@ -1983,6 +2010,7 @@
 		tempView->cmsToolbarButton->setChecked(tempDoc->HasCMS);
 		undoManager->switchStack(tempDoc->DocName);
 		styleManager->setDoc(tempDoc);
+		markersManager->setDoc(tempDoc);
 		tocGenerator->setDoc(tempDoc);
 	}
 	undoManager->setUndoEnabled(true);
@@ -2226,6 +2254,7 @@
 	docCheckerPalette->setDoc(doc);
 	tocGenerator->setDoc(doc);
 	styleManager->setDoc(doc);
+	markersManager->setDoc(doc);
 	symbolPalette->setDoc(doc);
 	modeToolBar->Angle->setValue(doc->itemToolPrefs().calligrapicPenAngle);
 	modeToolBar->PWidth->setValue(doc->itemToolPrefs().calligrapicPenWidth);
@@ -2257,6 +2286,7 @@
 	updateActiveWindowCaption(doc->DocName);
 // 	scrActions["shade100"]->setChecked(true);
 	propertiesPalette->setDoc(doc);
+	markersManager->setDoc(doc);
 	//propertiesPalette->Cpal->displayGradient(0);
 	pagePalette->setView(view);
 	layerPalette->setDoc(doc);
@@ -2396,6 +2426,7 @@
 //	scrActions["editPatterns"]->setEnabled(true);
 //	scrActions["editGradients"]->setEnabled(true);
  	scrActions["editStyles"]->setEnabled(true);
+	scrActions["editMarkers"]->setEnabled(true);
 	scrActions["editMasterPages"]->setEnabled(true);
 	scrActions["editJavascripts"]->setEnabled(true);
 
@@ -2462,6 +2493,7 @@
 	updateActiveWindowCaption(doc->DocName);
 // 	scrActions["shade100"]->setChecked(true);
 	propertiesPalette->setDoc(doc);
+	markersManager->setDoc(doc);
 	symbolPalette->setDoc(doc);
 //	propertiesPalette->Cpal->displayGradient(0);
 //	propertiesPalette->updateColorList();
@@ -2815,6 +2847,16 @@
 		scrActions["toolsCopyProperties"]->setEnabled(true);
 		scrActions["toolsEditWithStoryEditor"]->setEnabled(true);
 		scrActions["insertSampleText"]->setEnabled(true);
+		scrMenuMgr->setMenuEnabled("InsertMarker",true);
+		scrActions["insertMarkerAnchor"]->setEnabled(true);
+		scrActions["insertMarkerVariableText"]->setEnabled(true);
+		scrActions["insertMarkerItem"]->setEnabled(true);
+		scrActions["insertMarker2Marker"]->setEnabled(true);
+//		scrActions["insertMarkerFootnote"]->setEnabled(true);
+//		scrActions["insertMarkerEndnote"]->setEnabled(true);
+//		scrActions["insertMarkerIndex"]->setEnabled(true);
+		scrActions["editMarker"]->setEnabled(false);
+
 		if ((currItem->nextInChain() != 0) || (currItem->prevInChain() != 0))
 		{
 			scrActions["itemConvertToBezierCurve"]->setEnabled(false);
@@ -2843,6 +2885,8 @@
 			setTBvals(currItem);
 			scrActions["editSelectAll"]->setEnabled(true);
 			scrActions["editSelectAllOnLayer"]->setEnabled(false);
+			scrActions["insertSampleText"]->setEnabled(true);
+			scrMenuMgr->setMenuEnabled("InsertMarker",true);
 			charPalette->setEnabled(true, currItem);
 			if (currItem->asTextFrame())
 				enableTextActions(&scrActions, true, currItem->currentStyle().charStyle().font().scName());
@@ -2851,6 +2895,7 @@
 		}
 		else
 		{
+			scrMenuMgr->setMenuEnabled("InsertMarker",false);
 			doc->currentStyle = currItem->itemText.defaultStyle();
 			propertiesPalette->textPal->displayParStyle(doc->currentStyle.parent());
 			propertiesPalette->textPal->displayCharStyle(doc->currentStyle.charStyle().parent());
@@ -3209,6 +3254,7 @@
 //		scanDocument();
 //		docCheckerPalette->buildErrorList(doc);
 //	}
+//	doc->updateMarkers();
 	if (!doc->isModified())
 		doc->setModified(true);
 	updateActiveWindowCaption(doc->DocName + "*");
@@ -4185,6 +4231,7 @@
 			view->DrawNew();
 			slotDocCh();
 			styleManager->setDoc(doc);
+			markersManager->setDoc(doc);
 		}
 	}
 }
@@ -4585,6 +4632,7 @@
 //		scrActions["editPatterns"]->setEnabled(false);
 //		scrActions["editGradients"]->setEnabled(false);
 		scrActions["editStyles"]->setEnabled(false);
+		scrActions["editMarkers"]->setEnabled(false);
 		scrActions["editSearchReplace"]->setEnabled(false);
 		scrActions["editMasterPages"]->setEnabled(false);
 		scrActions["editJavascripts"]->setEnabled(false);
@@ -4690,6 +4738,7 @@
 	charPalette->setDoc(0);
 	tocGenerator->setDoc(0);
 	styleManager->setDoc(0);
+	markersManager->setDoc(0);
 	layerPalette->ClearInhalt();
 	docCheckerPalette->buildErrorList(0);
 	HaveDoc--;
@@ -5073,6 +5122,7 @@
 				styleManager->setDoc(doc);
 				propertiesPalette->unsetDoc();
 				propertiesPalette->setDoc(doc);
+				markersManager->setDoc(doc);
 				symbolPalette->unsetDoc();
 				symbolPalette->setDoc(doc);
 
@@ -5154,6 +5204,7 @@
 				styleManager->setDoc(doc);
 				propertiesPalette->unsetDoc();
 				propertiesPalette->setDoc(doc);
+				markersManager->setDoc(doc);
 				symbolPalette->unsetDoc();
 				symbolPalette->setDoc(doc);
 
@@ -6429,8 +6480,8 @@
 //					view->requestMode(modeEditClip);
 //					return;
 //				}
+				currItem->itemText.setCursorPosition(0);
 				setTBvals(currItem);
-				currItem->itemText.setCursorPosition(0);
 			}
 			scrActions["editPaste"]->setEnabled(false);
 			charPalette->setEnabled(true, currItem);
@@ -7770,6 +7821,7 @@
 	guidePalette->startup();
 	charPalette->startup();
 	styleManager->startup();
+	markersManager->startup();
 	symbolPalette->startup();
 
 	// init the toolbars
@@ -10035,6 +10087,7 @@
 	scrMenuMgr->setMenuEnabled("InsertQuote", enabled);
 	scrMenuMgr->setMenuEnabled("InsertSpace", enabled);
 	scrMenuMgr->setMenuEnabled("InsertLigature", enabled);
+	scrMenuMgr->setMenuEnabled("InsertMarker", enabled);
 }
 
 void ScribusMainWindow::updateTableMenuActions()
@@ -10066,4 +10119,76 @@
 	scrActions["tableAdjustFrameToTable"]->setEnabled(table);
 	scrActions["tableAdjustTableToFrame"]->setEnabled(table);
 }
+void ScribusMainWindow::insertMarker(MarkerType mType)
+{
+	if (HaveDoc && doc->m_Selection->itemAt(0)->isTextFrame() && doc->appMode == modeEdit)
+	{
+		doc->m_Selection->itemAt(0)->asTextFrame()->insertMarkerDlg(mType);
+		update();
+	}
+}
 
+void ScribusMainWindow::slotEditMarker()
+{
+	if (HaveDoc && doc->m_Selection->itemAt(0)->isTextFrame() && doc->appMode == modeEdit)
+	{
+		PageItem * currItem = doc->m_Selection->itemAt(0);
+		if (currItem->itemText.cursorPosition() < currItem->itemText.length())
+		{
+			ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+			if (hl->ch == SpecialChars::OBJECT && hl->marker != NULL)
+			{
+				currItem->asTextFrame()->editMarkerDlg(hl->marker);
+				slotUpdateMarkers();
+			}
+		}
+	}
+}
+
+void ScribusMainWindow::slotUpdateMarkers()
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	for(markIt = doc->markersMap.begin(); markIt != doc->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		int itemIndex = -1;
+		PageItem* item = doc->findMarker(marker, itemIndex);
+		while (item != NULL)
+		{
+			QString iName = item->getUName();
+			int cpos = -1;
+			if (doc->findMarkerCPos(marker, item, cpos))
+			{
+				ScText *hl = item->itemText.item(cpos);
+				if (hl->ch != SpecialChars::OBJECT || hl->marker == NULL)
+					continue;
+				if (hl->marker->getType() == marker->getType() && hl->marker->label == marker->label)
+				{
+					if (marker->getType() != MARKERVariableTextType)
+					{
+						marker->OwnPage = item->OwnPage;
+						if (marker->getType() == MARKER2ItemType)
+						{
+							PageItem* it = marker->getItemPtr();
+							if (it != NULL)
+								marker->setString(QString("%1").arg(it->OwnPage +1));
+							else
+								marker->setString("");
+						}
+						else if (marker->getType() == MARKER2MarkerType)
+						{
+							Marker* m = marker->getMarker();
+							if (m != NULL)
+								marker->setString(QString("%1").arg(m->OwnPage +1));
+							else
+								marker->setString("");
+						}
+					}
+					item->update();
+				}
+			}
+			item = doc->findMarker(marker,itemIndex);
+		}
+	}
+	doc->regionsChanged()->update(QRectF());
+}
Index: scribus/pageitem_textframe.h
===================================================================
--- scribus/pageitem_textframe.h	(wersja 17064)
+++ scribus/pageitem_textframe.h	(kopia robocza)
@@ -29,6 +29,7 @@
 
 #include "scribusapi.h"
 #include "pageitem.h"
+#include "markers.h"
 
 class ScPainter;
 class ScribusDoc;
@@ -76,7 +77,7 @@
 	int firstTextItem() const { return itemText.firstFrameItem; }
 	int lastTextItem() const { return itemText.lastFrameItem; }
 #endif
-	
+
 protected:
 	virtual void DrawObj_Item(ScPainter *p, QRectF e);
 	virtual void DrawObj_Post(ScPainter *p);
@@ -117,6 +118,9 @@
 	
 private slots:
 	void slotInvalidateLayout();
+public:
+	void insertMarkerDlg(MarkerType mT = MARKERAnchorType);
+	void editMarkerDlg(Marker * marker);
 };
 
 #endif
Index: scribus/plugins/scriptplugin/scriptercore.cpp
===================================================================
--- scribus/plugins/scriptplugin/scriptercore.cpp	(wersja 17064)
+++ scribus/plugins/scriptplugin/scriptercore.cpp	(kopia robocza)
@@ -18,6 +18,7 @@
 
 #include "runscriptdialog.h"
 #include "ui/helpbrowser.h"
+#include "ui/markersmanager.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
@@ -151,6 +152,7 @@
 	if (ScMW->HaveDoc)
 	{
 		ScMW->propertiesPalette->setDoc(ScMW->doc);
+		ScMW->markersManager->setDoc(ScMW->doc);
 		ScMW->layerPalette->setDoc(ScMW->doc);
 		ScMW->outlinePalette->setDoc(ScMW->doc);
 		ScMW->outlinePalette->BuildTree();
Index: scribus/plugins/fileloader/scribus150format/scribus150format.h
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format.h	(wersja 17064)
+++ scribus/plugins/fileloader/scribus150format/scribus150format.h	(kopia robocza)
@@ -122,7 +122,13 @@
 		bool readPrinterOptions(ScribusDoc* doc, ScXmlStreamReader& reader);
 		bool readSections(ScribusDoc* doc, ScXmlStreamReader& reader);
 		bool readTableOfContents(ScribusDoc* doc, ScXmlStreamReader& reader);
+		bool readMarkers(ScribusDoc* doc, ScXmlStreamReader& reader);
 
+		//lists of items and markers with names only, which need update to pointers
+		QMap<QString, Marker*> markeredItemsList;
+		QMap<Marker*, QMap<QString, MarkerType> > markeredMarkersList;
+		void updateMarkersPtr(); //after document load items pointers should be updated in markeredItemList
+
 		PageItem* pasteItem(ScribusDoc *doc, ScXmlStreamAttributes& attrs, const QString& baseDir, int pagenr = -2 /* currentPage*/);
 
 		void writeCheckerProfiles(ScXmlStreamWriter& docu);
@@ -148,6 +154,7 @@
 		void writePdfOptions(ScXmlStreamWriter& docu);
 		void writeDocItemAttributes(ScXmlStreamWriter& docu);
 		void writeTOC(ScXmlStreamWriter& docu);
+		void writeMarkers(ScXmlStreamWriter & docu);
 		void writePageSets(ScXmlStreamWriter& docu);
 		void writeSections(ScXmlStreamWriter& docu);
 		void writePatterns(ScXmlStreamWriter& docu, const QString& baseDir, bool part = false, Selection* selection = 0);
Index: scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp	(wersja 17064)
+++ scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp	(kopia robocza)
@@ -371,6 +371,7 @@
 	writePdfOptions(docu);
 	writeDocItemAttributes(docu);
 	writeTOC(docu);
+	writeMarkers(docu);
 	writePageSets(docu);
 	writeSections(docu);
 	writePatterns(docu, fileDir);
@@ -1035,6 +1036,35 @@
 	docu.writeEndElement();
 }
 
+void Scribus150Format::writeMarkers(ScXmlStreamWriter & docu)
+{
+	//write list of definied markers to SLA
+	docu.writeStartElement("Markers");
+	QMap<QString,Marker*>::Iterator markIt;
+	for(markIt = m_Doc->markersMap.begin(); markIt != m_Doc->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		docu.writeEmptyElement("Marker");
+		docu.writeAttribute("label", marker->label);
+		docu.writeAttribute("type", marker->getType());
+		if ((marker->getType() == MARKER2ItemType) && marker->hasItemPtr())
+		{
+			PageItem* item = marker->getItemPtr();
+			assert(item != NULL);
+			docu.writeAttribute("itemName", item->itemName());
+		}
+		else if ((marker->getType() == MARKERVariableTextType) && marker->hasString())
+			docu.writeAttribute("str", marker->getString());
+		else if ((marker->getType() == MARKER2MarkerType) && marker->hasMarker())
+		{
+			QString label = marker->getMarker()->label;
+			MarkerType type = marker->getMarker()->getType();
+			docu.writeAttribute("MARKlabel", label);
+			docu.writeAttribute("MARKtype", type);
+		}
+	}
+	docu.writeEndElement();
+}
 
 void Scribus150Format::writePageSets(ScXmlStreamWriter & docu) 
 {	
@@ -1232,6 +1262,13 @@
 			docu.writeAttribute("Unicode", tmpnum);
 			docu.writeAttribute("COBJ", qHash(item->itemText.object(k)));
 		}
+		else if (ch == SpecialChars::OBJECT && item->itemText.item(k)->marker != NULL)
+		{
+			Marker* mark = item->itemText.item(k)->marker;
+			docu.writeEmptyElement("MARKER");
+			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");
 		else if (ch == SpecialChars::TAB)
Index: scribus/plugins/fileloader/scribus150format/scribus150format.cpp
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format.cpp	(wersja 17064)
+++ scribus/plugins/fileloader/scribus150format/scribus150format.cpp	(kopia robocza)
@@ -369,6 +369,11 @@
 			success = readPattern(m_Doc, reader, fileDir);
 			if (!success) break;
 		}
+		if (tagName == "Markers")
+		{
+			success = readMarkers(m_Doc, reader);
+			if (!success) break;
+		}
 	}
 	if (reader.hasError())
 	{
@@ -829,6 +834,11 @@
 			success = readPattern(m_Doc, reader, fileDir);
 			if (!success) break;
 		}
+		if (tagName == "Markers")
+		{
+			success = readMarkers(m_Doc, reader);
+			if (!success) break;
+		}
 	}
 
 	if (reader.hasError())
@@ -1172,6 +1182,8 @@
 	WeldItems.clear();
 	WeldID.clear();
 	LinkID.clear();
+	markeredItemsList.clear();
+	markeredMarkersList.clear();
 
 	m_Doc->GroupCounter = 1;
 	m_Doc->LastAuto = 0;
@@ -1433,6 +1445,11 @@
 			if (!success)
 				break;
 		}
+		if (tagName == "Markers")
+		{
+			success = readMarkers(m_Doc, reader);
+			if (!success) break;
+		}
 	}
 
 	if (reader.hasError())
@@ -1724,7 +1741,9 @@
 			gItem->groupItemList = gpL;
 		}
 	}
-	
+
+	updateMarkersPtr();
+
 	// reestablish first/lastAuto
 	m_Doc->FirstAuto = m_Doc->LastAuto;
 	if (m_Doc->LastAuto)
@@ -2761,6 +2780,68 @@
 	return !reader.hasError();
 }
 
+bool Scribus150Format::readMarkers(ScribusDoc* doc, ScXmlStreamReader& reader)
+{
+	QStringRef tagName = reader.name();
+	doc->markersMap.clear();
+	markeredItemsList.clear();
+	markeredMarkersList.clear();
+	while(!reader.atEnd() && !reader.hasError())
+	{
+		reader.readNext();
+		if (reader.isEndElement() && reader.name() == tagName)
+			break;
+		if(reader.isStartElement() && reader.name() == "Marker")
+		{
+			ScXmlStreamAttributes attrs = reader.scAttributes();
+			MarkerData d;
+			d.itemName = "";
+			d.itemPtr = NULL;
+			d.mrkPtr = NULL;
+			d.strPtr = NULL;
+
+			QString label = "";
+			if (attrs.hasAttribute("label"))
+				label = attrs.valueAsString("label");
+
+			MarkerType type = MARKERNoType;
+			if (attrs.hasAttribute("type"))
+				type = (MarkerType) attrs.valueAsInt("type");
+
+			if (label != "" && type != MARKERNoType)
+			{
+				Marker* mark = new Marker;
+				mark->label=attrs.valueAsString("label");
+				mark->setType((MarkerType) attrs.valueAsInt("type"));
+				doc->markersMap.insert(mark->label, mark);
+
+				if (type == MARKERVariableTextType && attrs.hasAttribute("str"))
+					mark->setString(attrs.valueAsString("str"));
+				if (type == MARKER2ItemType && attrs.hasAttribute("itemName"))
+				{
+					QString itemName = attrs.valueAsString("itemName");
+					markeredItemsList.insert(itemName, mark);
+				}
+				if (type == MARKER2MarkerType && attrs.hasAttribute("MARKlabel"))
+				{
+					QString mark2Label = attrs.valueAsString("MARKlabel");
+					MarkerType mark2Type = (MarkerType) attrs.valueAsInt("MARKtype");
+					Marker* mark2 = doc->getMarkerDefinied(mark2Label, mark2Type);
+					if (mark2 != NULL) //marker is not defined yet, insert into temp list for update to pointers later
+						mark->setMarker(mark2);
+					else
+					{
+						QMap<QString, MarkerType> mark2map;
+						mark2map.insert(mark2Label, mark2Type);
+						markeredMarkersList.insert(mark, mark2map);
+					}
+				}
+			}
+		}
+	}
+	return !reader.hasError();
+}
+
 bool Scribus150Format::readSections(ScribusDoc* doc, ScXmlStreamReader& reader)
 {
 	QStringRef tagName = reader.name();
@@ -3214,6 +3295,25 @@
 				doc->Items = DItems;
 			}
 		}
+		if (tName == "MARKER")
+		{
+			if (newItem->asTextFrame())
+			{
+				QString l = tAtt.valueAsString("label");
+				MarkerType t = (MarkerType) tAtt.valueAsInt("type");
+				Marker* mark = m_Doc->getMarkerDefinied(l, t);
+				if (mark == NULL)
+					qDebug() << "Undefinied marker label ["<< l << "] type " << t;
+				else
+				{
+					//set pointer to item holds marker in his text
+					if (t == MARKERAnchorType)
+						mark->setItemPtr(newItem);
+					mark->OwnPage = newItem->OwnPage;
+					newItem->itemText.insertMarker(mark, newItem->itemText.length());
+				}
+			}
+		}
 		if (tName == "WeldEntry")
 		{
 			PageItem::weldingInfo wInf;
@@ -4529,6 +4629,8 @@
 	itemNextF.clear();
 	WeldItems.clear();
 	WeldID.clear();
+	markeredItemsList.clear();
+	markeredMarkersList.clear();
 
  	QString f(readSLA(fileName));
 	if (f.isEmpty())
@@ -5259,3 +5361,51 @@
 	*num2 = counter2;
 	return success;
 }
+void Scribus150Format::updateMarkersPtr() //after document load items pointers should be updated in markeredItemList
+{
+	if (!markeredItemsList.isEmpty())
+	{
+		QMap<QString,Marker*>::Iterator markIt;
+		for (markIt = markeredItemsList.begin(); markIt != markeredItemsList.end(); ++markIt)
+		{
+			QString itemName = markIt.key();
+			Marker* marker = markIt.value();
+			if (m_Doc->itemNameExists(itemName))
+			{
+				marker->setItemPtr(m_Doc->getItemFromName(itemName));
+				marker->setString(QString("%1").arg(marker->getItemPtr()->OwnPage +1));
+			}
+			else
+			{
+				qWarning() << "wrong marker [" << marker->label << "] data - item name [" << itemName << "] not exists - DELETING MARKER";
+				if (!m_Doc->eraseMarker(marker))
+					qWarning() << "Erase marker [" << marker->label << "] failed - was it definied?";
+			}
+		}
+	}
+	if (!markeredMarkersList.isEmpty())
+	{
+		QMap<Marker*,QMap<QString, MarkerType> >::iterator markIt;
+		for (markIt = markeredMarkersList.begin(); markIt != markeredMarkersList.end(); ++markIt)
+		{
+			Marker* mark = markIt.key();
+			QMap<QString, MarkerType> mark2map = markIt.value();
+			QString label2 = mark2map.begin().key();
+			MarkerType type2 = mark2map.begin().value();
+			Marker* mark2 = m_Doc->getMarkerDefinied(label2, type2);
+			if (mark2 != NULL)
+			{
+				mark->setMarker(mark2);
+				mark->setString(QString("%1").arg(mark2->getItemPtr()->OwnPage +1));
+			}
+			else
+			{
+				qWarning() << "wrong marker [" << mark->label << "] data - pointed merker name [" << label2 << "] not exists - DELETING MARKER";
+				if (!m_Doc->eraseMarker(mark))
+					qWarning() << "Erase marker [" << mark->label << "] failed - was it definied?";
+
+			}
+		}
+	}
+}
+
Index: scribus/scribus.h
===================================================================
--- scribus/scribus.h	(wersja 17064)
+++ scribus/scribus.h	(kopia robocza)
@@ -74,6 +74,7 @@
 class GuideManager;
 class HelpBrowser;
 class LayerPalette;
+class MarkersManager;
 class Measurements;
 class ScMWMenuManager;
 class ModeToolBar;
@@ -208,6 +209,7 @@
 	GuideManager *guidePalette;
 	CharSelect *charPalette;
 	PropertiesPalette *propertiesPalette;
+	MarkersManager *markersManager;
 	NodePalette *nodePalette;
 	OutlinePalette *outlinePalette;
 	Biblio *scrapbookPalette;
@@ -610,6 +612,20 @@
 	FormatsManager *formatsManager;
 
 	QPointer<HelpBrowser> helpBrowser;
+
+public slots:
+	//insert marker
+	void slotInsertMarker2Marker() { insertMarker(MARKER2MarkerType); }
+	void slotInsertMarkerAnchor() { insertMarker(MARKERAnchorType); }
+	void slotInsertMarkerVariableText() { insertMarker(MARKERVariableTextType); }
+	void slotInsertMarkerItem() { insertMarker(MARKER2ItemType); }
+	void slotInsertMarkerFootnote() { insertMarker(MARKERFootnoteType); }
+	void slotInsertMarkerEndnote() { insertMarker(MARKEREndnoteType); }
+	void slotInsertMarkerIndex() { insertMarker(MARKERIndexType); }
+	void slotEditMarker();
+	void slotUpdateMarkers();
+private:
+	void insertMarker(MarkerType);
 };
 
 #endif
Index: scribus/CMakeLists.txt
===================================================================
--- scribus/CMakeLists.txt	(wersja 17064)
+++ scribus/CMakeLists.txt	(kopia robocza)
@@ -85,6 +85,11 @@
   ui/inserttablerowsdialog.ui
   ui/latexeditor.ui
   ui/newmarginwidgetbase.ui
+ui/marker2item.ui
+ui/marker2marker.ui
+ui/markeranchor.ui
+ui/markervariabletext.ui
+ui/markersmanager.ui
   ui/measurementsbase.ui
   ui/multipleduplicate.ui
   ui/multiprogressdialog.ui
@@ -204,6 +209,7 @@
   latexhelpers.h
   loadsaveplugin.h
   menumanager.h
+markers.h
   navigator.h
   observable.h
   pageitem.h
@@ -310,6 +316,12 @@
   ui/latexeditor.h
   ui/layers.h
   ui/loremipsum.h
+ui/MarkerInsertDlg.h
+ui/marker2item.h
+ui/marker2marker.h
+ui/markeranchor.h
+ui/markervariabletext.h
+ui/markersmanager.h
   ui/margindialog.h
   ui/marginpresetlayout.h
   ui/marginwidget.h
@@ -734,6 +746,11 @@
   ui/linecombo.cpp
   ui/linkbutton.cpp
   ui/loremipsum.cpp
+ui/marker2item.cpp
+ui/marker2marker.cpp
+ui/markeranchor.cpp
+ui/markervariabletext.cpp
+ui/markersmanager.cpp
   ui/margindialog.cpp
   ui/marginpresetlayout.cpp
   ui/marginwidget.cpp
markers.patch (65,817 bytes)   

cezaryece

2011-12-09 14:28

updater  

markers.jpg (76,112 bytes)   
markers.jpg (76,112 bytes)   

cezaryece

2011-12-09 14:28

updater   ~0027345

You can see markers in usage on the screenshot

jghali

2011-12-18 12:50

administrator   ~0027365

It seems the patch is incomplete : the file 'ui/MarkerInsertDlg.h' is missing from it. Also according to our file naming convention, the file should be named 'ui/markerinsertdlg.h'.

cezaryece

2011-12-19 12:43

updater  

markers2.patch (64,892 bytes)   
Index: scribus/scribusdoc.cpp
===================================================================
--- scribus/scribusdoc.cpp	(wersja 17100)
+++ scribus/scribusdoc.cpp	(kopia robocza)
@@ -100,6 +100,12 @@
 #include "colormgmt/sccolormgmtenginefactory.h"
 #include "ui/hruler.h"
 #include "ui/layers.h"
+#include "ui/markerinsertdlgbase.h"
+#include "ui/marker2item.h"
+#include "ui/marker2marker.h"
+#include "ui/markeranchor.h"
+#include "ui/markervariabletext.h"
+#include "ui/markersmanager.h"
 #include "ui/scmessagebox.h"
 #include "ui/storyeditor.h"
 
@@ -628,6 +634,11 @@
 			delete pa.items.takeFirst();
 		}
 	}
+	QList<Marker*> marks = markersMap.values();
+	for (int i =0; i < marks.count(); ++i)
+		delete marks[i];
+	marks.clear();
+	markersMap.clear();
 	docPatterns.clear();
 	docGradients.clear();
 	while (!DocItems.isEmpty())
@@ -14608,6 +14619,327 @@
 	}
 }
 
+Marker* ScribusDoc::getMarkerDefinied(QString l, MarkerType t)
+{
+	if (markersMap.contains(l))
+	{
+		QList<Marker*> mlist = markersMap.values(l);
+		QList<Marker*>::const_iterator i;
+		for (i = mlist.constBegin(); i != mlist.constEnd(); ++i)
+		{
+			if ((*i)->getType() == t)
+				return (*i);
+		}
+	}
+	return NULL;
+}
+
+PageItem* ScribusDoc::findMarker(Marker* marker, int &lastItem)
+{
+	lastItem++;
+	for (int a = lastItem; a < Items->count(); ++a)
+	{
+		PageItem* currItem = Items->at(a);
+		if (currItem->isTextFrame() && currItem->itemText.length() > 0)
+		{
+			for (int i = currItem->firstInFrame(); i < currItem->itemText.length(); i++)
+			{
+				ScText* hl = currItem->itemText.item(i);
+				if ((hl->ch == SpecialChars::OBJECT) && (hl->marker == marker))
+				{
+					lastItem = a;
+					return currItem;
+				}
+			}
+		}
+	}
+	lastItem = 0;
+	return NULL;
+}
+
+PageItem* ScribusDoc::findMarker(Marker* marker)
+{
+	int temp = -1;
+	return findMarker(marker,temp);
+}
+
+PageItem* ScribusDoc::findMarker(QString label, MarkerType type)
+{
+	return findMarker(getMarkerDefinied(label, type));
+}
+
+bool ScribusDoc::findMarkerCPos(Marker* marker, PageItem* &currItem, int &pos)
+{
+	if (currItem->isTextFrame() && currItem->itemText.length() > 0)
+	{
+		for (pos = currItem->firstInFrame(); pos < currItem->itemText.length(); pos++)
+		{
+			ScText* hl = currItem->itemText.item(pos);
+			if ((hl->ch == SpecialChars::OBJECT) && (hl->marker == marker))
+				return true;
+		}
+	}
+	return false;
+}
+
+bool ScribusDoc::eraseMarker(Marker *marker)
+{
+	bool found = false;
+	QMap<QString, Marker*>::Iterator mIt = markersMap.find(marker->label);
+	//find markers pointed to that marker
+	while (mIt != markersMap.end())
+	{
+		Marker* mrk = (Marker*) mIt.value();
+		if ((mrk->getType()==MARKER2MarkerType) && (mrk->getMarker() == marker))
+			mrk->setMarker(NULL);
+		mIt++;
+	}
+	//find and delete all marker`s apperences in text
+	int MPos;
+	PageItem* item = findMarker(marker);
+	int itemIndex;
+	while (item != NULL)
+	{
+		itemIndex = DocItems.indexOf(item);
+		while (findMarkerCPos(marker, item, MPos))
+		{
+			item->itemText.select(MPos,1);
+			item->asTextFrame()->deleteSelectedTextFromFrame();
+		}
+		found = true;
+		item->update();
+		item = findMarker(marker,itemIndex);
+	}
+	mIt = markersMap.find(marker->label);
+	while (mIt != markersMap.end())
+	{
+		Marker* mrk = (Marker*) mIt.value();
+		if (mrk == marker)
+		{
+			markersMap.erase(mIt);
+			break;
+		}
+		mIt++;
+	}
+	return found;
+}
+
+bool ScribusDoc::eraseMarker(QString label, MarkerType type)
+{
+	return eraseMarker(getMarkerDefinied(label, type));
+}
+
+void ScribusDoc::editMarkerDlg(Marker * marker)
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	QVector<Marker*> markerList;
+	for(markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+		Marker* mark = markIt.value();
+		markerList.push_back(mark);
+	}
+	MarkerInsertDlg* editMDialog = NULL;
+	switch (marker->getType())
+	{
+	case MARKERAnchorType:
+		editMDialog = (MarkerInsertDlg*) new MarkerAnchorDlg(scMW());
+		editMDialog->setValues(marker->label);
+		break;
+	case MARKERVariableTextType:
+		editMDialog = (MarkerInsertDlg*) new MarkerVariableTextDlg(markerList, false, scMW());
+		editMDialog->setValues(marker->label, marker->getString());
+		break;
+	case MARKER2ItemType:
+		editMDialog = (MarkerInsertDlg*) new Marker2ItemDlg(scMW());
+		editMDialog->setValues(marker->label, marker->getItemPtr());
+		break;
+	case MARKER2MarkerType:
+		editMDialog = (MarkerInsertDlg*) new Marker2MarkerDlg(markerList, marker, scMW());
+		editMDialog->setValues(marker->label, marker->getMarker());
+		break;
+	case MARKERFootnoteType:
+		break;
+	case MARKEREndnoteType:
+		break;
+	case MARKERIndexType:
+		break;
+	default:
+		break;
+	}
+	editMDialog->setWindowTitle(tr("Edit ") + editMDialog->windowTitle());
+	if (editMDialog->exec())
+	{
+		Marker* Mrk = NULL;
+		MarkerData d;
+		 d.strPtr = NULL;
+		 d.itemPtr = NULL;
+		 d.mrkPtr = NULL;
+		 d.itemName = "";
+		QString label = "", text = "";
+		QString oldStr = marker->getString();
+		switch (marker->getType())
+		{
+		case MARKERAnchorType:
+			//only gets label for new marker
+			editMDialog->values(label);
+			if (label.isEmpty() || getMarkerDefinied(label, MARKERAnchorType) != NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			marker->label = label;
+			break;
+		case MARKERVariableTextType:
+			Mrk = editMDialog->values(label, text);
+			if (label.isEmpty() || text.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (Mrk != NULL)
+				marker = Mrk;
+			marker->label = label;
+			if (text != oldStr)
+			{
+				marker->setString(text);
+				updateMarkerVariableText(marker, true);
+			}
+			break;
+		case MARKER2ItemType:
+			editMDialog->values(label, d.itemPtr);
+			if (label.isEmpty() || d.itemPtr == NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.itemPtr != marker->getItemPtr())
+			{
+				marker->setItemPtr(d.itemPtr);
+				marker->setString(QString("%1").arg(d.itemPtr->OwnPage +1));
+			}
+			marker->label = label;
+			break;
+		case MARKER2MarkerType:
+			//gets pointer to referenced marker
+			editMDialog->values(label, d.mrkPtr);
+			if ((d.mrkPtr == NULL) && label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.mrkPtr == NULL)
+			{
+				marker->setMarker(d.mrkPtr);
+				marker->setString("");
+			}
+			else if (d.mrkPtr != marker->getMarker())
+			{
+				marker->setMarker(d.mrkPtr);
+				marker->setString(QString("%1").arg(d.mrkPtr->OwnPage +1));
+			}
+			marker->label = label;
+		case MARKERFootnoteType:
+			break;
+		case MARKEREndnoteType:
+			break;
+		case MARKERIndexType:
+			break;
+		default:
+			break;
+		}
+		changed();
+	}
+	delete editMDialog;
+}
+
+void ScribusDoc::updateMarkerVariableText(Marker* marker, bool forceUpdate)
+{
+	if (marker->getType() == MARKERVariableTextType)
+	{
+		int itemNo = -1;
+		PageItem* mItem = findMarker(marker, itemNo);
+		while (mItem != NULL)
+		{
+			if (forceUpdate)
+				mItem->layout();
+			else
+			{
+				mItem->invalidateLayout();
+			}
+			mItem = findMarker(marker, itemNo);
+		}
+	}
+}
+
+void ScribusDoc::updateMarkers() //update strings (page number) for markers pointed to anchors and items
+{
+	if (isLoading())
+		return;
+	QMap<QString,Marker*>::Iterator markIt;
+	//for all markers
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		//set marker page number
+		PageItem* mItem = findMarker(marker);
+		if (mItem != NULL)
+			marker->OwnPage = mItem->OwnPage;
+		else
+			marker->OwnPage = -1;
+	}
+	QList<Marker*> toDeleting;
+	//run for update markers to items
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		if (marker->getType() == MARKER2ItemType)
+		{
+			if (marker->getItemPtr() == NULL)  //pointer to item not set
+			{
+				qWarning() << "Wrong marker [" << marker->label << "] to item data - no item pointer and no item name - DELETING IT";
+				toDeleting.append(marker);
+				continue;
+			}
+			int page = marker->getItemPtr()->OwnPage +1;
+			if (marker->getString().toInt() != page)
+			{
+				marker->setString(QString("%1").arg(page));
+				(findMarker(marker))->invalidateLayout();
+			}
+		}
+	}
+	//run for markers to markers
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+
+		Marker* marker = markIt.value();
+		if (marker->getType() == MARKER2MarkerType)
+		{
+			Marker* destMark = marker->getMarker();
+			if (destMark == NULL)
+			{
+				qWarning() << QString("Update markers2markers: marker %1 - destination marker is NULL").arg(marker->label);
+				toDeleting.append(marker);
+				continue;
+			}
+			PageItem* mItem = findMarker(destMark);
+			if (mItem == NULL)
+			{
+				destMark->OwnPage = -1;
+				marker->setString("");
+			}
+			else
+			{
+				destMark->OwnPage = (findMarker(destMark))->OwnPage;
+				int page = destMark->OwnPage +1;
+				if (marker->getString().toInt() != page)
+				{
+					marker->setString(QString("%1").arg(page));
+					(findMarker(marker))->invalidateLayout();
+				}
+			}
+		}
+	}
+	//run for variable text (invalidate frames with variable text)
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+		updateMarkerVariableText(markIt.value(), false);
+	if (!toDeleting.isEmpty())
+	{
+		for (int i = 0; i < toDeleting.count(); i++)
+			eraseMarker(toDeleting.at(i));
+	}
+	scMW()->slotUpdateMarkers();
+	scMW()->markersManager->updateListView();
+}
+
 void ScribusDoc::itemSelection_UnWeld()
 {
 	PageItem *currItem;
Index: scribus/canvasmode_edit.cpp
===================================================================
--- scribus/canvasmode_edit.cpp	(wersja 17100)
+++ scribus/canvasmode_edit.cpp	(kopia robocza)
@@ -347,6 +347,11 @@
 				currItem->itemText.extendSelection(start, stop);
 				currItem->itemText.setCursorPosition(stop);
 			}
+			else if ((currItem->itemText.cursorPosition() < currItem->itemText.length()) && (currItem->itemText.item(currItem->itemText.cursorPosition())->marker != NULL))
+			{	//invoke edit marker dialog
+				m_ScMW->slotEditMarker();
+				return;
+			}
 			else
 			{	//Double click in a frame to select a word
 				oldCp = currItem->itemText.cursorPosition();
Index: scribus/sctextstruct.h
===================================================================
--- scribus/sctextstruct.h	(wersja 17100)
+++ scribus/sctextstruct.h	(kopia robocza)
@@ -28,6 +28,7 @@
 #include "styles/paragraphstyle.h"
 
 class PageItem;
+class Marker;
 
 /* Struktur fuer Pageitem Text */
 
@@ -116,7 +117,6 @@
 	InlineFrameData* d;
 };
 
-
 #ifndef NLS_PROTO
 class SCRIBUS_API ScText : public CharStyle
 {
@@ -128,16 +128,17 @@
 	float PRot;
 	float PDx;
 	InlineFrame embedded;
+	Marker* marker;
 	QChar ch;
 	ScText() : 
 		CharStyle(),
 		parstyle(NULL), glyph(), 
-		PtransX(0.0f), PtransY(0.0f), PRot(0.0f), PDx(0.0f), embedded(NULL), ch() {}
+		PtransX(0.0f), PtransY(0.0f), PRot(0.0f), PDx(0.0f), embedded(NULL), marker(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), marker(other.marker), ch(other.ch)
 	{
 		glyph.more = NULL;
 		GlyphLayout *layout = &glyph;
Index: scribus/pageitem.h
===================================================================
--- scribus/pageitem.h	(wersja 17100)
+++ scribus/pageitem.h	(kopia robocza)
@@ -237,15 +237,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();
Index: scribus/pageitem.cpp
===================================================================
--- scribus/pageitem.cpp	(wersja 17100)
+++ scribus/pageitem.cpp	(kopia robocza)
@@ -41,6 +41,7 @@
 #include "cmsettings.h"
 #include "colorblind.h"
 #include "commonstrings.h"
+#include "markers.h"
 
 #include "pageitem_group.h"
 #include "pageitem_textframe.h"
@@ -826,6 +827,20 @@
 	isInlineImage = false;
 }
 
+PageItem::~PageItem()
+{
+	if (tempImageFile != NULL)
+		delete tempImageFile;
+	//delete markers pointed to that item
+	QMap<QString,Marker*>::Iterator markIt;
+	for (markIt = doc()->markersMap.begin(); markIt != doc()->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		if ((marker->getType() == MARKER2ItemType) && (marker->getItemPtr() == this))
+			doc()->eraseMarker(marker);
+	}
+}
+
 void PageItem::setXPos(const double newXPos, bool drawingOnly)
 {
 	Xpos = newXPos;
@@ -2224,6 +2239,15 @@
 		else
 			return "%";
 	}
+	//check for markers
+	else if (ch == SpecialChars::OBJECT)
+	{
+		ScText* hl = itemText.item(base);
+		if (hl->marker != NULL && hl->marker->getType() != MARKERAnchorType && hl->marker->getType() != MARKERIndexType)
+		{
+			chstr = hl->marker->getString();
+		}
+	}
 	return chstr;
 }
 
@@ -2407,6 +2431,12 @@
 			points.addQuadPoint(0, -10, 0, -10, 0, -6, 0, -6);
 			stroke = true;
 		}
+		else if (glyph == SpecialChars::OBJECT.unicode())
+		{
+			points.resize(0);
+			points.addQuadPoint(0, -8, 1, -8, 0, -6, 1, -6);
+			stroke = true;
+		}
 		else // ???
 		{
 			points.resize(0);
Index: scribus/scribusdoc.h
===================================================================
--- scribus/scribusdoc.h	(wersja 17100)
+++ scribus/scribusdoc.h	(kopia robocza)
@@ -40,6 +40,7 @@
 #include "scribusapi.h"
 #include "colormgmt/sccolormgmtengine.h"
 #include "documentinformation.h"
+#include "markers.h"
 #include "observable.h"
 #include "pageitem.h"
 #include "pagestructs.h"
@@ -72,7 +73,7 @@
 class ScPattern;
 class UndoTransaction;
 class Serializer;
-
+class MarkersManager;
 class QProgressBar;
 
 struct SCRIBUS_API NodeEditContext : public MassObservable<QPointF>
@@ -1259,7 +1260,7 @@
 	MassObservable<ScPage*> m_pagesChanged;
 	MassObservable<QRectF> m_regionsChanged;
 	DocUpdater* m_docUpdater;
-	
+
 signals:
 	//Lets make our doc talk to our GUI rather than confusing all our normal stuff
 	/**
@@ -1520,8 +1521,24 @@
 	void updatePict(QString name);
 	void updatePictDir(QString name);
 	void removePict(QString name);
-//welding two items
+// Markers
+public:
+	//list of markers with its lables as keys
+	QMap<QString, Marker*> markersMap;
+	Marker* getMarkerDefinied(QString label, MarkerType type); //returns marker with label and type (labels are unique only for same type markers)
+	PageItem* findMarker(Marker* marker, int &lastItem);
+	PageItem* findMarker(Marker* marker);
+	PageItem* findMarker(QString label, MarkerType type);
+	bool findMarkerCPos(Marker* marker, PageItem* &item, int &CPos);
+	bool eraseMarker(QString label, MarkerType type);
+	bool eraseMarker(Marker* marker);
+	void editMarkerDlg(Marker*);
+	void updateMarkerVariableText(Marker* marker, bool forceUpdate = false); //returns if any text was changed
 public slots:
+	void updateMarkers(); //update strings (page number) for markers pointed to anchors and items
+
+	//welding two items
+public slots:
 	void itemSelection_UnWeld();
 	void itemSelection_Weld();
 	void itemSelection_EditWeld();
Index: scribus/actionmanager.cpp
===================================================================
--- scribus/actionmanager.cpp	(wersja 17100)
+++ scribus/actionmanager.cpp	(kopia robocza)
@@ -240,8 +240,11 @@
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 	name="editJavascripts";
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	name="editMarkers";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 
 	(*scrActions)["editStyles"]->setToggleAction(true);
+	(*scrActions)["editMarkers"]->setToggleAction(true);
 
 	connect( (*scrActions)["editUndoAction"], SIGNAL(triggeredData(int)) , undoManager, SLOT(undo(int)) );
 	connect( (*scrActions)["editRedoAction"], SIGNAL(triggeredData(int)) , undoManager, SLOT(redo(int)) );
@@ -540,10 +543,45 @@
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 	(*scrActions)["stickyTools"]->setToggleAction(true);
 
+	//Markers
+	name="insertMarkerAnchor";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarkerVariableText";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarkerItem";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarker2Marker";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+//	name="insertMarkerFootnote";
+//	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+//	(*scrActions)[name]->setEnabled(true);
+//	name="insertMarkerEndnote";
+//	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+//	(*scrActions)[name]->setEnabled(true);
+//	name="insertMarkerIndex";
+//	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+//	(*scrActions)[name]->setEnabled(true);
+	name="editMarker";
+	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)["insertMarkerAnchor"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerAnchor()) );
+	connect( (*scrActions)["insertMarkerVariableText"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerVariableText()) );
+	connect( (*scrActions)["insertMarkerItem"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerItem()) );
+	connect( (*scrActions)["insertMarker2Marker"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarker2Marker()) );
+//	connect( (*scrActions)["insertMarkerFootnote"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerFootnote()) );
+//	connect( (*scrActions)["insertMarkerEndnote"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerEndnote()) );
+//	connect( (*scrActions)["insertMarkerIndex"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerIndex()) );
+	connect( (*scrActions)["editMarker"], SIGNAL(triggered()), mainWindow, SLOT(slotEditMarker()) );
 }
 
 void ActionManager::initPageMenuActions()
@@ -1391,6 +1429,7 @@
 //	(*scrActions)["editPatterns"]->setTexts( tr("Patterns..."));
 //	(*scrActions)["editGradients"]->setTexts( tr("Gradients..."));
 	(*scrActions)["editStyles"]->setTexts( tr("S&tyles..."));
+	(*scrActions)["editMarkers"]->setTexts( tr("Markers..."));
 	(*scrActions)["editMasterPages"]->setTexts( tr("&Master Pages..."));
 	(*scrActions)["editJavascripts"]->setTexts( tr("&JavaScripts..."));
 
@@ -1485,6 +1524,14 @@
 	(*scrActions)["insertGlyph"]->setTexts( tr("&Glyph..."));
 	(*scrActions)["insertSampleText"]->setTexts( tr("Sample Text"));
 	(*scrActions)["stickyTools"]->setTexts( tr("Sticky Tools"));
+	(*scrActions)["insertMarkerAnchor"]->setTexts( tr("Anchor Marker"));
+	(*scrActions)["insertMarkerVariableText"]->setTexts( tr("Variable Text"));
+	(*scrActions)["insertMarkerItem"]->setTexts( tr("Reference to Item"));
+	(*scrActions)["insertMarker2Marker"]->setTexts( tr("Reference to Anchor Marker"));
+//	(*scrActions)["insertMarkerFootnote"]->setTexts( tr("Footnote"));
+//	(*scrActions)["insertMarkerEndnote"]->setTexts( tr("Endnote"));
+//	(*scrActions)["insertMarkerIndex"]->setTexts( tr("Index entry"));
+	(*scrActions)["editMarker"]->setTexts( tr("Edit Marker"));
 
 	//Page menu
 	(*scrActions)["pageInsert"]->setTexts( tr("&Insert..."));
@@ -1873,6 +1920,7 @@
 		<< "editReplaceColors"
 //		<< "editPatterns"
 		<< "editStyles"
+		<< "editMarkers"
 		<< "editMasterPages"
 		<< "editJavascripts";
 	//Style
@@ -1978,7 +2026,15 @@
 		<< "toolsInsertRenderFrame"
 		<< "stickyTools"
 		<< "insertGlyph"
-		<< "insertSampleText";
+		<< "insertSampleText"
+		<< "insertMarkerAnchor"
+		<< "insertMarkerVariableText"
+		<< "insertMarkerItem"
+		<< "insertMarker2Marker"
+//		<< "insertMarkerFootnote"
+//		<< "insertMarkerEndnote"
+//		<< "insertMarkerIndex"
+		<< "editMarker";
 
 	itmenu->second
 		<< "unicodeSoftHyphen"
Index: scribus/pageitem_textframe.cpp
===================================================================
--- scribus/pageitem_textframe.cpp	(wersja 17100)
+++ scribus/pageitem_textframe.cpp	(kopia robocza)
@@ -34,7 +34,9 @@
 
 #include "canvas.h"
 #include "commonstrings.h"
+#include "fonts/scface.h"
 #include "hyphenator.h"
+#include "markers.h"
 #include "pageitem.h"
 #include "pageitem_group.h"
 #include "pageitem_textframe.h"
@@ -53,6 +55,12 @@
 #include "util.h"
 #include "util_math.h"
 
+#include "ui/markerinsertdlgbase.h"
+#include "ui/marker2item.h"
+#include "ui/marker2marker.h"
+#include "ui/markeranchor.h"
+#include "ui/markervariabletext.h"
+#include "ui/markersmanager.h"
 #include "ui/guidemanager.h"
 
 #include <cairo.h>
@@ -1397,6 +1405,15 @@
 		for (int a = firstInFrame(); a < itemText.length(); ++a)
 		{
 			hl = itemText.item(a);
+			if (hl->ch == SpecialChars::OBJECT && hl->marker != NULL)
+			{
+				hl->glyph.glyph = SpecialChars::OBJECT.unicode() + ScFace::CONTROL_GLYPHS;
+				if (hl->marker->getType() == MARKERAnchorType || hl->marker->getType() == MARKERIndexType)
+				{
+					hl->glyph.shrink();
+					continue;
+				}
+			}
 			if (a > 0 && itemText.text(a-1) == SpecialChars::PARSEP)
 				style = itemText.paragraphStyle(a);
 			if (current.itemsInLine == 0)
@@ -1528,8 +1545,12 @@
 				// 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 = charStyle.font().realCharHeight(chstr[0], 1);
-				double realCharAscent = charStyle.font().realCharAscent(chstr[0], 1);
+				double realCharHeight = 0.0, realCharAscent = 0.0;
+				for (int i = 0; i < chstr.length(); i++)
+				{
+					realCharHeight = qMax(realCharHeight, charStyle.font().realCharHeight(chstr[i], 1));
+					realCharAscent = qMax(realCharAscent, charStyle.font().realCharAscent(chstr[i], 1));
+				}
 				double fontAscent     = charStyle.font().ascent(style.charStyle().fontSize() / 10.0);
 				if (realCharHeight == 0.0)
 					realCharHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
@@ -1594,11 +1615,19 @@
 				}
 				else
 				{
-					double realCharHeight = charStyle.font().realCharHeight(chstr[0], charStyle.fontSize() / 10.0);
+					double realCharHeight = 0.0;
+					wide = 0.0; realAsce = 0.0;
+					//
+					for (int i = 0; i < chstr.length(); i++)
+					{
+						realCharHeight = qMax(realCharHeight, charStyle.font().realCharHeight(chstr[i], charStyle.fontSize() / 10.0));
+						realAsce = qMax(realAsce, charStyle.font().realCharHeight(chstr[i], chsd / 10.0));
+						wide += charStyle.font().realCharWidth(chstr[i], chsd / 10.0);
+					}
+					wide = (wide* scaleH) + (1 - scaleH);
+					realAsce = realAsce  * scaleV + offset;
 					if (realCharHeight == 0)
 						realCharHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
-					wide = (charStyle.font().realCharWidth(chstr[0], chsd / 10.0) * scaleH) + (1 - scaleH); //dropcaps are to close to next glyphs if glyphs are hard scaled
-					realAsce = charStyle.font().realCharHeight(chstr[0], chsd / 10.0) * scaleV + offset;
 					asce = charStyle.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;
@@ -1622,12 +1651,19 @@
 					desc = realDesc = 0;
 				else
 				{
+					for (int i = 0; i < chstr.length(); i++)
+					{
+						if (chstr[i] == SpecialChars::OBJECT)
+							continue;
+						realDesc = qMax(realDesc, charStyle.font().realCharDescent(chstr[i], hlcsize10));
+						realAsce = charStyle.font().realCharAscent(chstr[i], hlcsize10);
+					}
+					realDesc =  realDesc * scaleV - offset;
 					desc = -charStyle.font().descent(hlcsize10);
-					realDesc = charStyle.font().realCharDescent(chstr[0], hlcsize10) * scaleV - offset;
 					current.rememberShrinkStretch(hl->ch, wide, style);
 				}
 				asce = charStyle.font().ascent(hlcsize10);
-				realAsce = charStyle.font().realCharAscent(chstr[0], hlcsize10) * scaleV + offset;
+				realAsce = realAsce * scaleV + offset;
 			}
 
 			//check for Y position at beginning of line
@@ -1938,7 +1974,12 @@
 			
 			// remember y pos
 			if (DropCmode)
-				hl->glyph.yoffset -= charStyle.font().realCharHeight(chstr[0], chsd / 10.0) - charStyle.font().realCharAscent(chstr[0], chsd / 10.0);
+			{
+				double yoffset = 0.0;
+				for (int i = 0; i < chstr.length(); i++)
+					yoffset = qMax(yoffset, charStyle.font().realCharHeight(chstr[i], chsd / 10.0) - charStyle.font().realCharAscent(chstr[i], chsd / 10.0));
+				hl->glyph.yoffset -= yoffset;
+			}
 			
 			// remember x pos
 			double breakPos = current.xPos;
@@ -2773,11 +2814,13 @@
 			{
 				bool selecteds = itemText.selected(as);
 				hls = itemText.item(as);
+				if (hls->marker != NULL && (hls->marker->getType() == MARKERAnchorType || hls->marker->getType() == MARKERIndexType))
+					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()) && (hls->ch == SpecialChars::OBJECT && hls->embedded.hasItem()))
 					    || previousWasObject)
 					{
 						sFList << selectedFrame;
@@ -2794,7 +2837,7 @@
 							asce = charStyleS.font().ascent(charStyleS.fontSize() / 10.0);
 							wide = hls->glyph.wide();
 							QRectF scr;
-							if ((hls->ch == SpecialChars::OBJECT)  && (hls->embedded.hasItem()))
+							if (hls->ch == SpecialChars::OBJECT && hls->embedded.hasItem())
 							{
 								double ww = (hls->embedded.getItem()->gWidth + hls->embedded.getItem()->lineWidth()) * hls->glyph.scaleH;
 								double hh = (hls->embedded.getItem()->gHeight + hls->embedded.getItem()->lineWidth()) * hls->glyph.scaleV;
@@ -4033,3 +4076,231 @@
 {
 	invalidateLayout();
 }
+
+void PageItem_TextFrame::insertMarkerDlg(MarkerType markerType)
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	QVector<Marker*> markerList;
+	for (markIt = m_Doc->markersMap.begin(); markIt != m_Doc->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		markerList.push_back(marker);
+	}
+	MarkerInsertDlg* insertMDialog = NULL;
+	switch (markerType)
+	{
+	case MARKERAnchorType:
+		insertMDialog = (MarkerInsertDlg*) new MarkerAnchorDlg(m_Doc->scMW());
+		break;
+	case MARKERVariableTextType:
+		insertMDialog = (MarkerInsertDlg*) new MarkerVariableTextDlg(markerList, true, m_Doc->scMW());
+		break;
+	case MARKER2ItemType:
+		insertMDialog = (MarkerInsertDlg*) new Marker2ItemDlg(m_Doc->scMW());
+		break;
+	case MARKER2MarkerType:
+		insertMDialog = (MarkerInsertDlg*) new Marker2MarkerDlg(markerList, NULL, m_Doc->scMW());
+		break;
+	case MARKERFootnoteType:
+		break;
+	case MARKEREndnoteType:
+		break;
+	case MARKERIndexType:
+		break;
+	}
+	if (insertMDialog == NULL)
+	{
+		qDebug() << "Dialog not implemented for markers type " << markerType;
+		return;
+	}
+	insertMDialog->setWindowTitle(tr("Insert new ") + insertMDialog->windowTitle());
+	if (insertMDialog->exec())
+	{
+		Marker* Mrk = NULL;
+		MarkerData d;
+		 d.strPtr = NULL;
+		 d.itemPtr = NULL;
+		 d.mrkPtr = NULL;
+		QString label = "", text = "";
+		switch (markerType)
+		{
+		case MARKERAnchorType:
+			//only gets label for new marker
+			insertMDialog->values(label);
+			if (label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.itemPtr = this;
+			break;
+		case MARKERVariableTextType:
+			Mrk = insertMDialog->values(label, text);
+			if ((Mrk == NULL) && (label.isEmpty() || text.isEmpty()))
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.strPtr = new QString(text);
+			break;
+		case MARKER2ItemType:
+			insertMDialog->values(label, d.itemPtr);
+			if (d.itemPtr == NULL || label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.strPtr = new QString(QString::number(d.itemPtr->OwnPage +1));
+			break;
+		case MARKER2MarkerType:
+			//gets pointer to referenced marker
+			insertMDialog->values(label, d.mrkPtr);
+			if (d.mrkPtr == NULL || label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.strPtr = new QString(QString::number(d.mrkPtr->OwnPage +1));
+		case MARKERFootnoteType:
+			break;
+		case MARKEREndnoteType:
+			break;
+		case MARKERIndexType:
+			break;
+		}
+		//check if marker with such label exist already
+		if (markerType != MARKERVariableTextType && m_Doc->getMarkerDefinied(label, markerType) != NULL)
+			return; //FIX ME here user should be warned that inserting of marker fails and why
+
+		if (Mrk == NULL)
+		{
+			Mrk = new Marker;
+			Mrk->setValues(label, OwnPage, markerType, d);
+			m_Doc->markersMap.insert(label,Mrk);
+		}
+		else
+		{ // that must be variable text marker
+			Mrk->setStrPtr(d.strPtr);
+			m_Doc->updateMarkerVariableText(Mrk, true);
+		}
+		itemText.insertMarker(Mrk);
+		Mrk->OwnPage = OwnPage;
+		update();
+		m_Doc->changed();
+	}
+	delete insertMDialog;
+	m_Doc->scMW()->markersManager->updateListView();
+}
+
+void PageItem_TextFrame::editMarkerDlg(Marker * marker)
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	QVector<Marker*> markerList;
+	for(markIt = m_Doc->markersMap.begin(); markIt != m_Doc->markersMap.end(); ++markIt)
+	{
+		Marker* mark = markIt.value();
+		markerList.push_back(mark);
+	}
+	MarkerInsertDlg* editMDialog = NULL;
+	switch (marker->getType())
+	{
+	case MARKERAnchorType:
+		editMDialog = (MarkerInsertDlg*) new MarkerAnchorDlg(m_Doc->scMW());
+		editMDialog->setValues(marker->label);
+		break;
+	case MARKERVariableTextType:
+		editMDialog = (MarkerInsertDlg*) new MarkerVariableTextDlg(markerList, true, m_Doc->scMW());
+		editMDialog->setValues(marker->label, marker->getString());
+		break;
+	case MARKER2ItemType:
+		editMDialog = (MarkerInsertDlg*) new Marker2ItemDlg(m_Doc->scMW());
+		editMDialog->setValues(marker->label, marker->getItemPtr());
+		break;
+	case MARKER2MarkerType:
+		editMDialog = (MarkerInsertDlg*) new Marker2MarkerDlg(markerList, marker, m_Doc->scMW());
+		editMDialog->setValues(marker->label, marker->getMarker());
+		break;
+	case MARKERFootnoteType:
+		break;
+	case MARKEREndnoteType:
+		break;
+	case MARKERIndexType:
+		break;
+	default:
+		break;
+	}
+	editMDialog->setWindowTitle(tr("Edit ") + editMDialog->windowTitle());
+	if (editMDialog->exec())
+	{
+		Marker* Mrk = NULL;
+		MarkerData d;
+		 d.strPtr = NULL;
+		 d.itemPtr = NULL;
+		 d.mrkPtr = NULL;
+		 d.itemName = "";
+		QString label = "", text = "";
+		QString oldStr = marker->getString();
+		switch (marker->getType())
+		{
+		case MARKERAnchorType:
+			//only gets label for new marker
+			editMDialog->values(label);
+			if (label.isEmpty() || m_Doc->getMarkerDefinied(label, MARKERAnchorType) != NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			marker->label = label;
+			break;
+		case MARKERVariableTextType:
+			Mrk = editMDialog->values(label, text);
+			if ((Mrk == NULL) && (label.isEmpty() || text.isEmpty()))
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (Mrk != NULL)
+			{
+				if (Mrk != marker)
+				{
+					ScText* hl = itemText.item(itemText.cursorPosition());
+					hl->marker = Mrk;
+					marker = Mrk;
+				}
+				marker->label = label;
+				if (text != oldStr)
+				{
+					marker->setString(text);
+					if (marker->getString() != oldStr)
+						m_Doc->updateMarkerVariableText(marker, true);
+				}
+			}
+			else
+			{
+				d.strPtr = new QString(text);
+				Mrk = new Marker;
+				Mrk->setValues(label, OwnPage, MARKERVariableTextType, d);
+				m_Doc->markersMap.insert(label,Mrk);
+				ScText* hl = itemText.item(itemText.cursorPosition());
+				hl->marker = Mrk;
+			}
+			break;
+		case MARKER2ItemType:
+			editMDialog->values(label, d.itemPtr);
+			if (label.isEmpty() || d.itemPtr == NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.itemPtr != marker->getItemPtr())
+			{
+				marker->setItemPtr(d.itemPtr);
+				marker->setString(QString("%1").arg(d.itemPtr->OwnPage +1));
+			}
+			marker->label = label;
+			break;
+		case MARKER2MarkerType:
+			//gets pointer to referenced marker
+			editMDialog->values(label, d.mrkPtr);
+			if ((d.mrkPtr == NULL) && label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.mrkPtr != marker->getMarker())
+			{
+				marker->setMarker(d.mrkPtr);
+				marker->setString(QString("%1").arg(d.mrkPtr->OwnPage +1));
+			}
+			marker->label = label;
+		case MARKERFootnoteType:
+			break;
+		case MARKEREndnoteType:
+			break;
+		case MARKERIndexType:
+			break;
+		default:
+			break;
+		}
+		update();
+		m_Doc->changed();
+		m_Doc->scMW()->markersManager->updateListView();
+	}
+	delete editMDialog;
+}
Index: scribus/ui/markerinsertdlgbase.h
===================================================================
--- scribus/ui/markerinsertdlgbase.h	(wersja 0)
+++ scribus/ui/markerinsertdlgbase.h	(wersja 0)
@@ -0,0 +1,39 @@
+#ifndef MARKERINSERTDLG_H
+#define MARKERINSERTDLG_H
+
+#include <QDialog>
+#include <scribusapi.h>
+
+class NotesSet;
+class Marker;
+class PageItem;
+
+class SCRIBUS_API MarkerInsertDlg : public QDialog
+{
+	Q_OBJECT
+
+public:
+	MarkerInsertDlg(const QVector<Marker*>&, QWidget *parent = 0) : QDialog(parent) {}
+	MarkerInsertDlg(const QList<NotesSet*>&, QWidget *parent = 0) : QDialog(parent) {}
+	MarkerInsertDlg(QWidget *parent = 0) : QDialog(parent) {}
+	~MarkerInsertDlg() {}
+
+	virtual void values(QString &label) {}
+	virtual void values(QString &label, PageItem* &item) {}
+	virtual Marker* values(QString& label, QString& text) { return NULL; }
+	virtual void values(QString& label, Marker* &marker) {}
+	virtual NotesSet* values() { return NULL; }
+
+	virtual void setValues(const QString label) {}
+	virtual void setValues(const QString label, const QString text) {}
+	virtual void setValues(const QString label, const PageItem* ptr) {}
+	virtual void setValues(const QString label, const Marker* ptr) {}
+	virtual void setValues(const NotesSet* defaultSet) {}
+	
+signals:
+
+public slots:
+
+};
+
+#endif // MARKERINSERTDLG_H
Index: scribus/ui/contextmenu.cpp
===================================================================
--- scribus/ui/contextmenu.cpp	(wersja 17100)
+++ scribus/ui/contextmenu.cpp	(kopia robocza)
@@ -94,6 +94,7 @@
 	QMenu *menuLayer = new QMenu(this);
 	QMenu *menuLevel = new QMenu(this);
 	QMenu *menuPDF = new QMenu(this);
+	QMenu *menuMarker = new QMenu(this);
 	QMenu *menuResolution = new QMenu(this);
 	QMenu *menuWeld = new QMenu(this);
 	
@@ -172,6 +173,25 @@
 			addAction(m_AP->scrActions["fileImportAppendText"]);
 			addAction(m_AP->scrActions["toolsEditWithStoryEditor"]);
 			addAction(m_AP->scrActions["insertSampleText"]);
+			if (m_doc->appMode == modeEdit)
+			{
+				QAction *act2 = addMenu(menuMarker);
+				act2->setText( ScribusView::tr("Insert Marker"));
+				menuMarker->addAction(m_AP->scrActions["insertMarkerAnchor"]);
+				menuMarker->addAction(m_AP->scrActions["insertMarkerVariableText"]);
+				menuMarker->addAction(m_AP->scrActions["insertMarkerItem"]);
+				menuMarker->addAction(m_AP->scrActions["insertMarker2Marker"]);
+//				menuMarker->addAction(m_AP->scrActions["insertMarkerFootnote"]);
+//				menuMarker->addAction(m_AP->scrActions["insertMarkerEndnote"]);
+//				menuMarker->addAction(m_AP->scrActions["insertMarkerIndex"]);
+				if (currItem->itemText.cursorPosition() < currItem->itemText.length())
+				{
+					ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+					if (hl->ch == SpecialChars::OBJECT && hl->marker != NULL)
+						addAction(m_AP->scrActions["editMarker"]);
+				}
+
+			}
 		}
 		else //enable this for, eg, text on a path
 			if (m_actionList.contains("toolsEditWithStoryEditor"))
Index: scribus/text/storytext.cpp
===================================================================
--- scribus/text/storytext.cpp	(wersja 17100)
+++ scribus/text/storytext.cpp	(kopia robocza)
@@ -329,10 +329,13 @@
 		if ((it->ch == SpecialChars::PARSEP)) {
 			removeParSep(i);
 		}
+		Marker* mrk = it->marker;
 //		qDebug("remove char %d at %d", (int) it->ch.unicode(), i);
 		d->takeAt(i);
 		d->len--;
 		delete it;
+		if ((mrk != NULL) && mrk->isUnique())
+			doc->eraseMarker(mrk);
 		// #9592 : adjust selFirst and selLast, those values have to be
 		// consistent in functions such as select()
 		if (i <= selLast) --selLast;
@@ -477,6 +480,15 @@
 	invalidate(pos, pos + 1);
 }
 
+void StoryText::insertMarker(Marker* M, int pos)
+{
+	if (pos < 0)
+		pos = d->cursorPosition;
+
+	insertChars(pos, SpecialChars::OBJECT);
+	const_cast<StoryText *>(this)->d->at(pos)->marker = M;
+}
+
 void StoryText::hyphenateWord(int pos, uint len, char* hyphens)
 {
 	assert(pos >= 0);
Index: scribus/text/storytext.h
===================================================================
--- scribus/text/storytext.h	(wersja 17100)
+++ scribus/text/storytext.h	(kopia robocza)
@@ -126,6 +126,8 @@
 	// Insert object at specific position
  	void insertObject(int pos, PageItem* obj);
  	void replaceChar(int pos, QChar ch);
+	// Insert marker at cursor or specific position
+	void insertMarker(Marker* M, int pos = -1);
 
 	void hyphenateWord(int pos, uint len, char* hyphens);
 	
Index: scribus/scribus.cpp
===================================================================
--- scribus/scribus.cpp	(wersja 17100)
+++ scribus/scribus.cpp	(kopia robocza)
@@ -99,6 +99,7 @@
 #include "gtgettext.h"
 #include "hyphenator.h"
 #include "langmgr.h"
+#include "markers.h"
 #include "pageitem_group.h"
 #include "pageitem_imageframe.h"
 #include "pageitem_latexframe.h"
@@ -163,6 +164,8 @@
 #include "ui/loremipsum.h"
 #include "ui/marginwidget.h"
 #include "ui/margindialog.h"
+#include "ui/markerinsertdlgbase.h"
+#include "ui/markersmanager.h"
 #include "ui/masterpagepalette.h"
 #include "ui/mergedoc.h"
 #include "ui/movepage.h"
@@ -582,6 +585,12 @@
 	connect( styleManager, SIGNAL(paletteShown(bool)), scrActions["editStyles"], SLOT(setChecked(bool)));
 	styleManager->installEventFilter(this);
 
+	// initializing marker`s manager
+	markersManager = new MarkersManager(this, "markersManager");
+	connect( scrActions["editMarkers"], SIGNAL(toggled(bool)), markersManager, SLOT(setPaletteShown(bool)) );
+	connect( markersManager, SIGNAL(paletteShown(bool)), scrActions["editMarkers"], SLOT(setChecked(bool)));
+	markersManager->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)));
@@ -721,6 +730,7 @@
 //	scrMenuMgr->addMenuItem(scrActions["editGradients"], "Edit", false);
 //	scrMenuMgr->addMenuItem(scrActions["editPatterns"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editStyles"], "Edit", false);
+	scrMenuMgr->addMenuItem(scrActions["editMarkers"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editMasterPages"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editJavascripts"], "Edit", false);
 	scrMenuMgr->setMenuEnabled("EditPasteRecent", false);
@@ -837,6 +847,8 @@
 	scrMenuMgr->addMenuItem(scrActions["itemWeld"], "Item", false);
 	scrMenuMgr->addMenuItem(scrActions["itemEditWeld"], "Item", false);
 
+	scrMenuMgr->addMenuItem(scrActions["editMarker"], "Item", false);
+
 	//Insert menu
 	scrMenuMgr->createMenu("Insert", ActionManager::defaultMenuNameEntryTranslated("Insert"));
 	scrMenuMgr->addMenuItem(scrActions["insertFrame"], "Insert", false);
@@ -927,6 +939,15 @@
 
 	scrMenuMgr->addMenuSeparator("Insert");
 	scrMenuMgr->addMenuItem(scrActions["insertSampleText"], "Insert", false);
+	scrMenuMgr->addMenuSeparator("Insert");
+	scrMenuMgr->createMenu("InsertMarker", tr("Markers"), "Insert");
+	scrMenuMgr->addMenuItem(scrActions["insertMarkerAnchor"], "InsertMarker", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarkerVariableText"], "InsertMarker", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarkerItem"], "InsertMarker", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarker2Marker"], "InsertMarker", false);
+//	scrMenuMgr->addMenuItem(scrActions["insertMarkerFootnote"], "InsertMarker", false);
+//	scrMenuMgr->addMenuItem(scrActions["insertMarkerEndnote"], "InsertMarker", false);
+//	scrMenuMgr->addMenuItem(scrActions["insertMarkerIndex"], "InsertMarker", false);
 
 	//Page menu
 	scrMenuMgr->createMenu("Page", ActionManager::defaultMenuNameEntryTranslated("Page"));
@@ -1129,6 +1150,7 @@
 //AV to be replaced with Selection::update and listener in PropertiesPalette
 void ScribusMainWindow::setTBvals(PageItem *currItem)
 {
+	scrActions["editMarker"]->setEnabled(false);
 	if (currItem->itemText.length() != 0)
 	{
 //		int ChPos = qMin(currItem->CPos, static_cast<int>(currItem->itemText.length()-1));
@@ -1142,6 +1164,11 @@
 		emit TextStyle(doc->currentStyle);
 		// to go: (av)
 		propertiesPalette->textPal->updateStyle(doc->currentStyle);
+		if (doc->appMode == modeEdit && currItem->itemText.cursorPosition() < currItem->itemText.length())
+		{
+			ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+			scrActions["editMarker"]->setEnabled((hl->ch == SpecialChars::OBJECT && hl->marker != NULL));
+		}
 	}
 }
 
@@ -1984,6 +2011,7 @@
 		tempView->cmsToolbarButton->setChecked(tempDoc->HasCMS);
 		undoManager->switchStack(tempDoc->DocName);
 		styleManager->setDoc(tempDoc);
+		markersManager->setDoc(tempDoc);
 		tocGenerator->setDoc(tempDoc);
 	}
 	undoManager->setUndoEnabled(true);
@@ -2227,6 +2255,7 @@
 	docCheckerPalette->setDoc(doc);
 	tocGenerator->setDoc(doc);
 	styleManager->setDoc(doc);
+	markersManager->setDoc(doc);
 	symbolPalette->setDoc(doc);
 	modeToolBar->Angle->setValue(doc->itemToolPrefs().calligrapicPenAngle);
 	modeToolBar->PWidth->setValue(doc->itemToolPrefs().calligrapicPenWidth);
@@ -2258,6 +2287,7 @@
 	updateActiveWindowCaption(doc->DocName);
 // 	scrActions["shade100"]->setChecked(true);
 	propertiesPalette->setDoc(doc);
+	markersManager->setDoc(doc);
 	//propertiesPalette->Cpal->displayGradient(0);
 	pagePalette->setView(view);
 	layerPalette->setDoc(doc);
@@ -2397,6 +2427,7 @@
 //	scrActions["editPatterns"]->setEnabled(true);
 //	scrActions["editGradients"]->setEnabled(true);
  	scrActions["editStyles"]->setEnabled(true);
+	scrActions["editMarkers"]->setEnabled(true);
 	scrActions["editMasterPages"]->setEnabled(true);
 	scrActions["editJavascripts"]->setEnabled(true);
 
@@ -2463,6 +2494,7 @@
 	updateActiveWindowCaption(doc->DocName);
 // 	scrActions["shade100"]->setChecked(true);
 	propertiesPalette->setDoc(doc);
+	markersManager->setDoc(doc);
 	symbolPalette->setDoc(doc);
 //	propertiesPalette->Cpal->displayGradient(0);
 //	propertiesPalette->updateColorList();
@@ -2816,6 +2848,16 @@
 		scrActions["toolsCopyProperties"]->setEnabled(true);
 		scrActions["toolsEditWithStoryEditor"]->setEnabled(true);
 		scrActions["insertSampleText"]->setEnabled(true);
+		scrMenuMgr->setMenuEnabled("InsertMarker",true);
+		scrActions["insertMarkerAnchor"]->setEnabled(true);
+		scrActions["insertMarkerVariableText"]->setEnabled(true);
+		scrActions["insertMarkerItem"]->setEnabled(true);
+		scrActions["insertMarker2Marker"]->setEnabled(true);
+//		scrActions["insertMarkerFootnote"]->setEnabled(true);
+//		scrActions["insertMarkerEndnote"]->setEnabled(true);
+//		scrActions["insertMarkerIndex"]->setEnabled(true);
+		scrActions["editMarker"]->setEnabled(false);
+
 		if ((currItem->nextInChain() != 0) || (currItem->prevInChain() != 0))
 		{
 			scrActions["itemConvertToBezierCurve"]->setEnabled(false);
@@ -2844,6 +2886,8 @@
 			setTBvals(currItem);
 			scrActions["editSelectAll"]->setEnabled(true);
 			scrActions["editSelectAllOnLayer"]->setEnabled(false);
+			scrActions["insertSampleText"]->setEnabled(true);
+			scrMenuMgr->setMenuEnabled("InsertMarker",true);
 			charPalette->setEnabled(true, currItem);
 			if (currItem->asTextFrame())
 				enableTextActions(&scrActions, true, currItem->currentStyle().charStyle().font().scName());
@@ -2852,6 +2896,7 @@
 		}
 		else
 		{
+			scrMenuMgr->setMenuEnabled("InsertMarker",false);
 			doc->currentStyle = currItem->itemText.defaultStyle();
 			propertiesPalette->textPal->displayParStyle(doc->currentStyle.parent());
 			propertiesPalette->textPal->displayCharStyle(doc->currentStyle.charStyle().parent());
@@ -3204,6 +3249,7 @@
 //		scanDocument();
 //		docCheckerPalette->buildErrorList(doc);
 //	}
+//	doc->updateMarkers();
 	if (!doc->isModified())
 		doc->setModified(true);
 	updateActiveWindowCaption(doc->DocName + "*");
@@ -4180,6 +4226,7 @@
 			view->DrawNew();
 			slotDocCh();
 			styleManager->setDoc(doc);
+			markersManager->setDoc(doc);
 		}
 	}
 }
@@ -4580,6 +4627,7 @@
 //		scrActions["editPatterns"]->setEnabled(false);
 //		scrActions["editGradients"]->setEnabled(false);
 		scrActions["editStyles"]->setEnabled(false);
+		scrActions["editMarkers"]->setEnabled(false);
 		scrActions["editSearchReplace"]->setEnabled(false);
 		scrActions["editMasterPages"]->setEnabled(false);
 		scrActions["editJavascripts"]->setEnabled(false);
@@ -4685,6 +4733,7 @@
 	charPalette->setDoc(0);
 	tocGenerator->setDoc(0);
 	styleManager->setDoc(0);
+	markersManager->setDoc(0);
 	layerPalette->ClearInhalt();
 	docCheckerPalette->buildErrorList(0);
 	HaveDoc--;
@@ -5068,6 +5117,7 @@
 				styleManager->setDoc(doc);
 				propertiesPalette->unsetDoc();
 				propertiesPalette->setDoc(doc);
+				markersManager->setDoc(doc);
 				symbolPalette->unsetDoc();
 				symbolPalette->setDoc(doc);
 
@@ -5149,6 +5199,7 @@
 				styleManager->setDoc(doc);
 				propertiesPalette->unsetDoc();
 				propertiesPalette->setDoc(doc);
+				markersManager->setDoc(doc);
 				symbolPalette->unsetDoc();
 				symbolPalette->setDoc(doc);
 
@@ -6424,8 +6475,8 @@
 //					view->requestMode(modeEditClip);
 //					return;
 //				}
+				currItem->itemText.setCursorPosition(0);
 				setTBvals(currItem);
-				currItem->itemText.setCursorPosition(0);
 			}
 			scrActions["editPaste"]->setEnabled(false);
 			charPalette->setEnabled(true, currItem);
@@ -7766,6 +7817,7 @@
 	guidePalette->startup();
 	charPalette->startup();
 	styleManager->startup();
+	markersManager->startup();
 	symbolPalette->startup();
 
 	// init the toolbars
@@ -10031,6 +10083,7 @@
 	scrMenuMgr->setMenuEnabled("InsertQuote", enabled);
 	scrMenuMgr->setMenuEnabled("InsertSpace", enabled);
 	scrMenuMgr->setMenuEnabled("InsertLigature", enabled);
+	scrMenuMgr->setMenuEnabled("InsertMarker", enabled);
 }
 
 void ScribusMainWindow::updateTableMenuActions()
@@ -10062,4 +10115,76 @@
 	scrActions["tableAdjustFrameToTable"]->setEnabled(table);
 	scrActions["tableAdjustTableToFrame"]->setEnabled(table);
 }
+void ScribusMainWindow::insertMarker(MarkerType mType)
+{
+	if (HaveDoc && doc->m_Selection->itemAt(0)->isTextFrame() && doc->appMode == modeEdit)
+	{
+		doc->m_Selection->itemAt(0)->asTextFrame()->insertMarkerDlg(mType);
+		update();
+	}
+}
 
+void ScribusMainWindow::slotEditMarker()
+{
+	if (HaveDoc && doc->m_Selection->itemAt(0)->isTextFrame() && doc->appMode == modeEdit)
+	{
+		PageItem * currItem = doc->m_Selection->itemAt(0);
+		if (currItem->itemText.cursorPosition() < currItem->itemText.length())
+		{
+			ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+			if (hl->ch == SpecialChars::OBJECT && hl->marker != NULL)
+			{
+				currItem->asTextFrame()->editMarkerDlg(hl->marker);
+				slotUpdateMarkers();
+			}
+		}
+	}
+}
+
+void ScribusMainWindow::slotUpdateMarkers()
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	for(markIt = doc->markersMap.begin(); markIt != doc->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		int itemIndex = -1;
+		PageItem* item = doc->findMarker(marker, itemIndex);
+		while (item != NULL)
+		{
+			QString iName = item->getUName();
+			int cpos = -1;
+			if (doc->findMarkerCPos(marker, item, cpos))
+			{
+				ScText *hl = item->itemText.item(cpos);
+				if (hl->ch != SpecialChars::OBJECT || hl->marker == NULL)
+					continue;
+				if (hl->marker->getType() == marker->getType() && hl->marker->label == marker->label)
+				{
+					if (marker->getType() != MARKERVariableTextType)
+					{
+						marker->OwnPage = item->OwnPage;
+						if (marker->getType() == MARKER2ItemType)
+						{
+							PageItem* it = marker->getItemPtr();
+							if (it != NULL)
+								marker->setString(QString("%1").arg(it->OwnPage +1));
+							else
+								marker->setString("");
+						}
+						else if (marker->getType() == MARKER2MarkerType)
+						{
+							Marker* m = marker->getMarker();
+							if (m != NULL)
+								marker->setString(QString("%1").arg(m->OwnPage +1));
+							else
+								marker->setString("");
+						}
+					}
+					item->update();
+				}
+			}
+			item = doc->findMarker(marker,itemIndex);
+		}
+	}
+	doc->regionsChanged()->update(QRectF());
+}
Index: scribus/pageitem_textframe.h
===================================================================
--- scribus/pageitem_textframe.h	(wersja 17100)
+++ scribus/pageitem_textframe.h	(kopia robocza)
@@ -29,6 +29,7 @@
 
 #include "scribusapi.h"
 #include "pageitem.h"
+#include "markers.h"
 
 class ScPainter;
 class ScribusDoc;
@@ -76,7 +77,7 @@
 	int firstTextItem() const { return itemText.firstFrameItem; }
 	int lastTextItem() const { return itemText.lastFrameItem; }
 #endif
-	
+
 protected:
 	virtual void DrawObj_Item(ScPainter *p, QRectF e);
 	virtual void DrawObj_Post(ScPainter *p);
@@ -117,6 +118,9 @@
 	
 private slots:
 	void slotInvalidateLayout();
+public:
+	void insertMarkerDlg(MarkerType mT = MARKERAnchorType);
+	void editMarkerDlg(Marker * marker);
 };
 
 #endif
Index: scribus/plugins/scriptplugin/scriptercore.cpp
===================================================================
--- scribus/plugins/scriptplugin/scriptercore.cpp	(wersja 17100)
+++ scribus/plugins/scriptplugin/scriptercore.cpp	(kopia robocza)
@@ -18,6 +18,7 @@
 
 #include "runscriptdialog.h"
 #include "ui/helpbrowser.h"
+#include "ui/markersmanager.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
@@ -151,6 +152,7 @@
 	if (ScMW->HaveDoc)
 	{
 		ScMW->propertiesPalette->setDoc(ScMW->doc);
+		ScMW->markersManager->setDoc(ScMW->doc);
 		ScMW->layerPalette->setDoc(ScMW->doc);
 		ScMW->outlinePalette->setDoc(ScMW->doc);
 		ScMW->outlinePalette->BuildTree();
Index: scribus/plugins/fileloader/scribus150format/scribus150format.h
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format.h	(wersja 17100)
+++ scribus/plugins/fileloader/scribus150format/scribus150format.h	(kopia robocza)
@@ -122,7 +122,13 @@
 		bool readPrinterOptions(ScribusDoc* doc, ScXmlStreamReader& reader);
 		bool readSections(ScribusDoc* doc, ScXmlStreamReader& reader);
 		bool readTableOfContents(ScribusDoc* doc, ScXmlStreamReader& reader);
+		bool readMarkers(ScribusDoc* doc, ScXmlStreamReader& reader);
 
+		//lists of items and markers with names only, which need update to pointers
+		QMap<QString, Marker*> markeredItemsList;
+		QMap<Marker*, QMap<QString, MarkerType> > markeredMarkersList;
+		void updateMarkersPtr(); //after document load items pointers should be updated in markeredItemList
+
 		PageItem* pasteItem(ScribusDoc *doc, ScXmlStreamAttributes& attrs, const QString& baseDir, int pagenr = -2 /* currentPage*/);
 
 		void writeCheckerProfiles(ScXmlStreamWriter& docu);
@@ -148,6 +154,7 @@
 		void writePdfOptions(ScXmlStreamWriter& docu);
 		void writeDocItemAttributes(ScXmlStreamWriter& docu);
 		void writeTOC(ScXmlStreamWriter& docu);
+		void writeMarkers(ScXmlStreamWriter & docu);
 		void writePageSets(ScXmlStreamWriter& docu);
 		void writeSections(ScXmlStreamWriter& docu);
 		void writePatterns(ScXmlStreamWriter& docu, const QString& baseDir, bool part = false, Selection* selection = 0);
Index: scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp	(wersja 17100)
+++ scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp	(kopia robocza)
@@ -371,6 +371,7 @@
 	writePdfOptions(docu);
 	writeDocItemAttributes(docu);
 	writeTOC(docu);
+	writeMarkers(docu);
 	writePageSets(docu);
 	writeSections(docu);
 	writePatterns(docu, fileDir);
@@ -1035,6 +1036,35 @@
 	docu.writeEndElement();
 }
 
+void Scribus150Format::writeMarkers(ScXmlStreamWriter & docu)
+{
+	//write list of definied markers to SLA
+	docu.writeStartElement("Markers");
+	QMap<QString,Marker*>::Iterator markIt;
+	for(markIt = m_Doc->markersMap.begin(); markIt != m_Doc->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		docu.writeEmptyElement("Marker");
+		docu.writeAttribute("label", marker->label);
+		docu.writeAttribute("type", marker->getType());
+		if ((marker->getType() == MARKER2ItemType) && marker->hasItemPtr())
+		{
+			PageItem* item = marker->getItemPtr();
+			assert(item != NULL);
+			docu.writeAttribute("itemName", item->itemName());
+		}
+		else if ((marker->getType() == MARKERVariableTextType) && marker->hasString())
+			docu.writeAttribute("str", marker->getString());
+		else if ((marker->getType() == MARKER2MarkerType) && marker->hasMarker())
+		{
+			QString label = marker->getMarker()->label;
+			MarkerType type = marker->getMarker()->getType();
+			docu.writeAttribute("MARKlabel", label);
+			docu.writeAttribute("MARKtype", type);
+		}
+	}
+	docu.writeEndElement();
+}
 
 void Scribus150Format::writePageSets(ScXmlStreamWriter & docu) 
 {	
@@ -1232,6 +1262,13 @@
 			docu.writeAttribute("Unicode", tmpnum);
 			docu.writeAttribute("COBJ", qHash(item->itemText.object(k)));
 		}
+		else if (ch == SpecialChars::OBJECT && item->itemText.item(k)->marker != NULL)
+		{
+			Marker* mark = item->itemText.item(k)->marker;
+			docu.writeEmptyElement("MARKER");
+			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");
 		else if (ch == SpecialChars::TAB)
Index: scribus/plugins/fileloader/scribus150format/scribus150format.cpp
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format.cpp	(wersja 17100)
+++ scribus/plugins/fileloader/scribus150format/scribus150format.cpp	(kopia robocza)
@@ -369,6 +369,11 @@
 			success = readPattern(m_Doc, reader, fileDir);
 			if (!success) break;
 		}
+		if (tagName == "Markers")
+		{
+			success = readMarkers(m_Doc, reader);
+			if (!success) break;
+		}
 	}
 	if (reader.hasError())
 	{
@@ -829,6 +834,11 @@
 			success = readPattern(m_Doc, reader, fileDir);
 			if (!success) break;
 		}
+		if (tagName == "Markers")
+		{
+			success = readMarkers(m_Doc, reader);
+			if (!success) break;
+		}
 	}
 
 	if (reader.hasError())
@@ -1172,6 +1182,9 @@
 	WeldItems.clear();
 	WeldID.clear();
 	LinkID.clear();
+	markeredItemsList.clear();
+	markeredMarkersList.clear();
+	
 
 	m_Doc->GroupCounter = 1;
 	m_Doc->LastAuto = 0;
@@ -1433,6 +1446,11 @@
 			if (!success)
 				break;
 		}
+		if (tagName == "Markers")
+		{
+			success = readMarkers(m_Doc, reader);
+			if (!success) break;
+		}
 	}
 
 	if (reader.hasError())
@@ -1724,6 +1742,7 @@
 			gItem->groupItemList = gpL;
 		}
 	}
+	updateMarkersPtr();
 	
 	// reestablish first/lastAuto
 	m_Doc->FirstAuto = m_Doc->LastAuto;
@@ -2761,6 +2780,68 @@
 	return !reader.hasError();
 }
 
+bool Scribus150Format::readMarkers(ScribusDoc* doc, ScXmlStreamReader& reader)
+{
+	QStringRef tagName = reader.name();
+	doc->markersMap.clear();
+	markeredItemsList.clear();
+	markeredMarkersList.clear();
+	while(!reader.atEnd() && !reader.hasError())
+	{
+		reader.readNext();
+		if (reader.isEndElement() && reader.name() == tagName)
+			break;
+		if(reader.isStartElement() && reader.name() == "Marker")
+		{
+			ScXmlStreamAttributes attrs = reader.scAttributes();
+			MarkerData d;
+			d.itemName = "";
+			d.itemPtr = NULL;
+			d.mrkPtr = NULL;
+			d.strPtr = NULL;
+
+			QString label = "";
+			if (attrs.hasAttribute("label"))
+				label = attrs.valueAsString("label");
+
+			MarkerType type = MARKERNoType;
+			if (attrs.hasAttribute("type"))
+				type = (MarkerType) attrs.valueAsInt("type");
+
+			if (label != "" && type != MARKERNoType)
+			{
+				Marker* mark = new Marker;
+				mark->label=attrs.valueAsString("label");
+				mark->setType((MarkerType) attrs.valueAsInt("type"));
+				doc->markersMap.insert(mark->label, mark);
+
+				if (type == MARKERVariableTextType && attrs.hasAttribute("str"))
+					mark->setString(attrs.valueAsString("str"));
+				if (type == MARKER2ItemType && attrs.hasAttribute("itemName"))
+				{
+					QString itemName = attrs.valueAsString("itemName");
+					markeredItemsList.insert(itemName, mark);
+				}
+				if (type == MARKER2MarkerType && attrs.hasAttribute("MARKlabel"))
+				{
+					QString mark2Label = attrs.valueAsString("MARKlabel");
+					MarkerType mark2Type = (MarkerType) attrs.valueAsInt("MARKtype");
+					Marker* mark2 = doc->getMarkerDefinied(mark2Label, mark2Type);
+					if (mark2 != NULL) //marker is not defined yet, insert into temp list for update to pointers later
+						mark->setMarker(mark2);
+					else
+					{
+						QMap<QString, MarkerType> mark2map;
+						mark2map.insert(mark2Label, mark2Type);
+						markeredMarkersList.insert(mark, mark2map);
+					}
+				}
+			}
+		}
+	}
+	return !reader.hasError();
+}
+
 bool Scribus150Format::readSections(ScribusDoc* doc, ScXmlStreamReader& reader)
 {
 	QStringRef tagName = reader.name();
@@ -3214,6 +3295,25 @@
 				doc->Items = DItems;
 			}
 		}
+		if (tName == "MARKER")
+		{
+			if (newItem->asTextFrame())
+			{
+				QString l = tAtt.valueAsString("label");
+				MarkerType t = (MarkerType) tAtt.valueAsInt("type");
+				Marker* mark = m_Doc->getMarkerDefinied(l, t);
+				if (mark == NULL)
+					qDebug() << "Undefinied marker label ["<< l << "] type " << t;
+				else
+				{
+					//set pointer to item holds marker in his text
+					if (t == MARKERAnchorType)
+						mark->setItemPtr(newItem);
+					mark->OwnPage = newItem->OwnPage;
+					newItem->itemText.insertMarker(mark, newItem->itemText.length());
+				}
+			}
+		}
 		if (tName == "WeldEntry")
 		{
 			PageItem::weldingInfo wInf;
@@ -4529,6 +4629,9 @@
 	itemNextF.clear();
 	WeldItems.clear();
 	WeldID.clear();
+	markeredItemsList.clear();
+	markeredMarkersList.clear();
+	
 
  	QString f(readSLA(fileName));
 	if (f.isEmpty())
@@ -5259,3 +5362,51 @@
 	*num2 = counter2;
 	return success;
 }
+
+void Scribus150Format::updateMarkersPtr() //after document load items pointers should be updated in markeredItemList
+{
+	if (!markeredItemsList.isEmpty())
+	{
+		QMap<QString,Marker*>::Iterator markIt;
+		for (markIt = markeredItemsList.begin(); markIt != markeredItemsList.end(); ++markIt)
+		{
+			QString itemName = markIt.key();
+			Marker* marker = markIt.value();
+			if (m_Doc->itemNameExists(itemName))
+			{
+				marker->setItemPtr(m_Doc->getItemFromName(itemName));
+				marker->setString(QString("%1").arg(marker->getItemPtr()->OwnPage +1));
+			}
+			else
+			{
+				qWarning() << "wrong marker [" << marker->label << "] data - item name [" << itemName << "] not exists - DELETING MARKER";
+				if (!m_Doc->eraseMarker(marker))
+					qWarning() << "Erase marker [" << marker->label << "] failed - was it definied?";
+			}
+		}
+	}
+	if (!markeredMarkersList.isEmpty())
+	{
+		QMap<Marker*,QMap<QString, MarkerType> >::iterator markIt;
+		for (markIt = markeredMarkersList.begin(); markIt != markeredMarkersList.end(); ++markIt)
+		{
+			Marker* mark = markIt.key();
+			QMap<QString, MarkerType> mark2map = markIt.value();
+			QString label2 = mark2map.begin().key();
+			MarkerType type2 = mark2map.begin().value();
+			Marker* mark2 = m_Doc->getMarkerDefinied(label2, type2);
+			if (mark2 != NULL)
+			{
+				mark->setMarker(mark2);
+				mark->setString(QString("%1").arg(mark2->getItemPtr()->OwnPage +1));
+			}
+			else
+			{
+				qWarning() << "wrong marker [" << mark->label << "] data - pointed merker name [" << label2 << "] not exists - DELETING MARKER";
+				if (!m_Doc->eraseMarker(mark))
+					qWarning() << "Erase marker [" << mark->label << "] failed - was it definied?";
+
+			}
+		}
+	}
+}
Index: scribus/scribus.h
===================================================================
--- scribus/scribus.h	(wersja 17100)
+++ scribus/scribus.h	(kopia robocza)
@@ -74,6 +74,7 @@
 class GuideManager;
 class HelpBrowser;
 class LayerPalette;
+class MarkersManager;
 class Measurements;
 class ScMWMenuManager;
 class ModeToolBar;
@@ -208,6 +209,7 @@
 	GuideManager *guidePalette;
 	CharSelect *charPalette;
 	PropertiesPalette *propertiesPalette;
+	MarkersManager *markersManager;
 	NodePalette *nodePalette;
 	OutlinePalette *outlinePalette;
 	Biblio *scrapbookPalette;
@@ -611,6 +613,20 @@
 	FormatsManager *formatsManager;
 
 	QPointer<HelpBrowser> helpBrowser;
+
+public slots:
+	//insert marker
+	void slotInsertMarker2Marker() { insertMarker(MARKER2MarkerType); }
+	void slotInsertMarkerAnchor() { insertMarker(MARKERAnchorType); }
+	void slotInsertMarkerVariableText() { insertMarker(MARKERVariableTextType); }
+	void slotInsertMarkerItem() { insertMarker(MARKER2ItemType); }
+	void slotInsertMarkerFootnote() { insertMarker(MARKERFootnoteType); }
+	void slotInsertMarkerEndnote() { insertMarker(MARKEREndnoteType); }
+	void slotInsertMarkerIndex() { insertMarker(MARKERIndexType); }
+	void slotEditMarker();
+	void slotUpdateMarkers();
+private:
+	void insertMarker(MarkerType);
 };
 
 #endif
Index: scribus/CMakeLists.txt
===================================================================
--- scribus/CMakeLists.txt	(wersja 17100)
+++ scribus/CMakeLists.txt	(kopia robocza)
@@ -85,6 +85,11 @@
   ui/inserttablerowsdialog.ui
   ui/latexeditor.ui
   ui/newmarginwidgetbase.ui
+ui/marker2item.ui
+ui/marker2marker.ui
+ui/markeranchor.ui
+ui/markervariabletext.ui
+ui/markersmanager.ui
   ui/measurementsbase.ui
   ui/multipleduplicate.ui
   ui/multiprogressdialog.ui
@@ -204,6 +209,7 @@
   latexhelpers.h
   loadsaveplugin.h
   menumanager.h
+markers.h
   navigator.h
   observable.h
   pageitem.h
@@ -310,6 +316,12 @@
   ui/latexeditor.h
   ui/layers.h
   ui/loremipsum.h
+ui/markerinsertdlgbase.h
+ui/marker2item.h
+ui/marker2marker.h
+ui/markeranchor.h
+ui/markervariabletext.h
+ui/markersmanager.h
   ui/margindialog.h
   ui/marginpresetlayout.h
   ui/marginwidget.h
@@ -734,6 +746,11 @@
   ui/linecombo.cpp
   ui/linkbutton.cpp
   ui/loremipsum.cpp
+ui/marker2item.cpp
+ui/marker2marker.cpp
+ui/markeranchor.cpp
+ui/markervariabletext.cpp
+ui/markersmanager.cpp
   ui/margindialog.cpp
   ui/marginpresetlayout.cpp
   ui/marginwidget.cpp
markers2.patch (64,892 bytes)   

cezaryece

2011-12-19 12:43

updater   ~0027370

fixed

cbradney

2012-01-04 19:38

administrator   ~0027453

Is this now ready for inclusion? Has it been tested enough to a) work itself and b) not interfere with other things?

jghali

2012-01-04 20:25

administrator   ~0027455

No, patch is still incomplete. Several files are still missing from patch. Amongst others :
ui/marker2item.ui
ui/marker2marker.ui
ui/markeranchor.ui
ui/markersmanager.ui
ui/markervariabletext.ui

cezaryece

2012-01-05 08:39

updater   ~0027460

Grrrr... forget to add new files to SVN tree. Now new files are in patch...

cezaryece

2012-01-05 08:39

updater  

markers3.patch (80,348 bytes)   
 
Index: scribus/scribusdoc.cpp
===================================================================
--- scribus/scribusdoc.cpp	(wersja 17181)
+++ scribus/scribusdoc.cpp	(kopia robocza)
@@ -100,6 +100,12 @@
 #include "colormgmt/sccolormgmtenginefactory.h"
 #include "ui/hruler.h"
 #include "ui/layers.h"
+#include "ui/markerinsertdlgbase.h"
+#include "ui/marker2item.h"
+#include "ui/marker2marker.h"
+#include "ui/markeranchor.h"
+#include "ui/markervariabletext.h"
+#include "ui/markersmanager.h"
 #include "ui/scmessagebox.h"
 #include "ui/storyeditor.h"
 
@@ -635,6 +641,11 @@
 			delete pa.items.takeFirst();
 		}
 	}
+	QList<Marker*> marks = markersMap.values();
+	for (int i =0; i < marks.count(); ++i)
+		delete marks[i];
+	marks.clear();
+	markersMap.clear();
 	docPatterns.clear();
 	docGradients.clear();
 	while (!DocItems.isEmpty())
@@ -14627,6 +14638,327 @@
 	}
 }
 
+Marker* ScribusDoc::getMarkerDefinied(QString l, MarkerType t)
+{
+	if (markersMap.contains(l))
+	{
+		QList<Marker*> mlist = markersMap.values(l);
+		QList<Marker*>::const_iterator i;
+		for (i = mlist.constBegin(); i != mlist.constEnd(); ++i)
+		{
+			if ((*i)->getType() == t)
+				return (*i);
+		}
+	}
+	return NULL;
+}
+
+PageItem* ScribusDoc::findMarker(Marker* marker, int &lastItem)
+{
+	lastItem++;
+	for (int a = lastItem; a < Items->count(); ++a)
+	{
+		PageItem* currItem = Items->at(a);
+		if (currItem->isTextFrame() && currItem->itemText.length() > 0)
+		{
+			for (int i = currItem->firstInFrame(); i < currItem->itemText.length(); i++)
+			{
+				ScText* hl = currItem->itemText.item(i);
+				if ((hl->ch == SpecialChars::OBJECT) && (hl->marker == marker))
+				{
+					lastItem = a;
+					return currItem;
+				}
+			}
+		}
+	}
+	lastItem = 0;
+	return NULL;
+}
+
+PageItem* ScribusDoc::findMarker(Marker* marker)
+{
+	int temp = -1;
+	return findMarker(marker,temp);
+}
+
+PageItem* ScribusDoc::findMarker(QString label, MarkerType type)
+{
+	return findMarker(getMarkerDefinied(label, type));
+}
+
+bool ScribusDoc::findMarkerCPos(Marker* marker, PageItem* &currItem, int &pos)
+{
+	if (currItem->isTextFrame() && currItem->itemText.length() > 0)
+	{
+		for (pos = currItem->firstInFrame(); pos < currItem->itemText.length(); pos++)
+		{
+			ScText* hl = currItem->itemText.item(pos);
+			if ((hl->ch == SpecialChars::OBJECT) && (hl->marker == marker))
+				return true;
+		}
+	}
+	return false;
+}
+
+bool ScribusDoc::eraseMarker(Marker *marker)
+{
+	bool found = false;
+	QMap<QString, Marker*>::Iterator mIt = markersMap.find(marker->label);
+	//find markers pointed to that marker
+	while (mIt != markersMap.end())
+	{
+		Marker* mrk = (Marker*) mIt.value();
+		if ((mrk->getType()==MARKER2MarkerType) && (mrk->getMarker() == marker))
+			mrk->setMarker(NULL);
+		mIt++;
+	}
+	//find and delete all marker`s apperences in text
+	int MPos;
+	PageItem* item = findMarker(marker);
+	int itemIndex;
+	while (item != NULL)
+	{
+		itemIndex = DocItems.indexOf(item);
+		while (findMarkerCPos(marker, item, MPos))
+		{
+			item->itemText.select(MPos,1);
+			item->asTextFrame()->deleteSelectedTextFromFrame();
+		}
+		found = true;
+		item->update();
+		item = findMarker(marker,itemIndex);
+	}
+	mIt = markersMap.find(marker->label);
+	while (mIt != markersMap.end())
+	{
+		Marker* mrk = (Marker*) mIt.value();
+		if (mrk == marker)
+		{
+			markersMap.erase(mIt);
+			break;
+		}
+		mIt++;
+	}
+	return found;
+}
+
+bool ScribusDoc::eraseMarker(QString label, MarkerType type)
+{
+	return eraseMarker(getMarkerDefinied(label, type));
+}
+
+void ScribusDoc::editMarkerDlg(Marker * marker)
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	QVector<Marker*> markerList;
+	for(markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+		Marker* mark = markIt.value();
+		markerList.push_back(mark);
+	}
+	MarkerInsertDlg* editMDialog = NULL;
+	switch (marker->getType())
+	{
+	case MARKERAnchorType:
+		editMDialog = (MarkerInsertDlg*) new MarkerAnchorDlg(scMW());
+		editMDialog->setValues(marker->label);
+		break;
+	case MARKERVariableTextType:
+		editMDialog = (MarkerInsertDlg*) new MarkerVariableTextDlg(markerList, false, scMW());
+		editMDialog->setValues(marker->label, marker->getString());
+		break;
+	case MARKER2ItemType:
+		editMDialog = (MarkerInsertDlg*) new Marker2ItemDlg(scMW());
+		editMDialog->setValues(marker->label, marker->getItemPtr());
+		break;
+	case MARKER2MarkerType:
+		editMDialog = (MarkerInsertDlg*) new Marker2MarkerDlg(markerList, marker, scMW());
+		editMDialog->setValues(marker->label, marker->getMarker());
+		break;
+	case MARKERFootnoteType:
+		break;
+	case MARKEREndnoteType:
+		break;
+	case MARKERIndexType:
+		break;
+	default:
+		break;
+	}
+	editMDialog->setWindowTitle(tr("Edit ") + editMDialog->windowTitle());
+	if (editMDialog->exec())
+	{
+		Marker* Mrk = NULL;
+		MarkerData d;
+		 d.strPtr = NULL;
+		 d.itemPtr = NULL;
+		 d.mrkPtr = NULL;
+		 d.itemName = "";
+		QString label = "", text = "";
+		QString oldStr = marker->getString();
+		switch (marker->getType())
+		{
+		case MARKERAnchorType:
+			//only gets label for new marker
+			editMDialog->values(label);
+			if (label.isEmpty() || getMarkerDefinied(label, MARKERAnchorType) != NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			marker->label = label;
+			break;
+		case MARKERVariableTextType:
+			Mrk = editMDialog->values(label, text);
+			if (label.isEmpty() || text.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (Mrk != NULL)
+				marker = Mrk;
+			marker->label = label;
+			if (text != oldStr)
+			{
+				marker->setString(text);
+				updateMarkerVariableText(marker, true);
+			}
+			break;
+		case MARKER2ItemType:
+			editMDialog->values(label, d.itemPtr);
+			if (label.isEmpty() || d.itemPtr == NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.itemPtr != marker->getItemPtr())
+			{
+				marker->setItemPtr(d.itemPtr);
+				marker->setString(QString("%1").arg(d.itemPtr->OwnPage +1));
+			}
+			marker->label = label;
+			break;
+		case MARKER2MarkerType:
+			//gets pointer to referenced marker
+			editMDialog->values(label, d.mrkPtr);
+			if ((d.mrkPtr == NULL) && label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.mrkPtr == NULL)
+			{
+				marker->setMarker(d.mrkPtr);
+				marker->setString("");
+			}
+			else if (d.mrkPtr != marker->getMarker())
+			{
+				marker->setMarker(d.mrkPtr);
+				marker->setString(QString("%1").arg(d.mrkPtr->OwnPage +1));
+			}
+			marker->label = label;
+		case MARKERFootnoteType:
+			break;
+		case MARKEREndnoteType:
+			break;
+		case MARKERIndexType:
+			break;
+		default:
+			break;
+		}
+		changed();
+	}
+	delete editMDialog;
+}
+
+void ScribusDoc::updateMarkerVariableText(Marker* marker, bool forceUpdate)
+{
+	if (marker->getType() == MARKERVariableTextType)
+	{
+		int itemNo = -1;
+		PageItem* mItem = findMarker(marker, itemNo);
+		while (mItem != NULL)
+		{
+			if (forceUpdate)
+				mItem->layout();
+			else
+			{
+				mItem->invalidateLayout();
+			}
+			mItem = findMarker(marker, itemNo);
+		}
+	}
+}
+
+void ScribusDoc::updateMarkers() //update strings (page number) for markers pointed to anchors and items
+{
+	if (isLoading())
+		return;
+	QMap<QString,Marker*>::Iterator markIt;
+	//for all markers
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		//set marker page number
+		PageItem* mItem = findMarker(marker);
+		if (mItem != NULL)
+			marker->OwnPage = mItem->OwnPage;
+		else
+			marker->OwnPage = -1;
+	}
+	QList<Marker*> toDeleting;
+	//run for update markers to items
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		if (marker->getType() == MARKER2ItemType)
+		{
+			if (marker->getItemPtr() == NULL)  //pointer to item not set
+			{
+				qWarning() << "Wrong marker [" << marker->label << "] to item data - no item pointer and no item name - DELETING IT";
+				toDeleting.append(marker);
+				continue;
+			}
+			int page = marker->getItemPtr()->OwnPage +1;
+			if (marker->getString().toInt() != page)
+			{
+				marker->setString(QString("%1").arg(page));
+				(findMarker(marker))->invalidateLayout();
+			}
+		}
+	}
+	//run for markers to markers
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+
+		Marker* marker = markIt.value();
+		if (marker->getType() == MARKER2MarkerType)
+		{
+			Marker* destMark = marker->getMarker();
+			if (destMark == NULL)
+			{
+				qWarning() << QString("Update markers2markers: marker %1 - destination marker is NULL").arg(marker->label);
+				toDeleting.append(marker);
+				continue;
+			}
+			PageItem* mItem = findMarker(destMark);
+			if (mItem == NULL)
+			{
+				destMark->OwnPage = -1;
+				marker->setString("");
+			}
+			else
+			{
+				destMark->OwnPage = (findMarker(destMark))->OwnPage;
+				int page = destMark->OwnPage +1;
+				if (marker->getString().toInt() != page)
+				{
+					marker->setString(QString("%1").arg(page));
+					(findMarker(marker))->invalidateLayout();
+				}
+			}
+		}
+	}
+	//run for variable text (invalidate frames with variable text)
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+		updateMarkerVariableText(markIt.value(), false);
+	if (!toDeleting.isEmpty())
+	{
+		for (int i = 0; i < toDeleting.count(); i++)
+			eraseMarker(toDeleting.at(i));
+	}
+	scMW()->slotUpdateMarkers();
+	scMW()->markersManager->updateListView();
+}
+
 void ScribusDoc::itemSelection_UnWeld()
 {
 	PageItem *currItem;
Index: scribus/canvasmode_edit.cpp
===================================================================
--- scribus/canvasmode_edit.cpp	(wersja 17181)
+++ scribus/canvasmode_edit.cpp	(kopia robocza)
@@ -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())->marker != NULL))
+			{	//invoke edit marker dialog
+				m_ScMW->slotEditMarker();
+				return;
+			}
 			else
 			{	//Double click in a frame to select a word
 				oldCp = currItem->itemText.cursorPosition();
Index: scribus/sctextstruct.h
===================================================================
--- scribus/sctextstruct.h	(wersja 17181)
+++ scribus/sctextstruct.h	(kopia robocza)
@@ -28,6 +28,7 @@
 #include "styles/paragraphstyle.h"
 
 class PageItem;
+class Marker;
 
 /* Struktur fuer Pageitem Text */
 
@@ -116,7 +117,6 @@
 	InlineFrameData* d;
 };
 
-
 #ifndef NLS_PROTO
 class SCRIBUS_API ScText : public CharStyle
 {
@@ -128,16 +128,17 @@
 	float PRot;
 	float PDx;
 	InlineFrame embedded;
+	Marker* marker;
 	QChar ch;
 	ScText() : 
 		CharStyle(),
 		parstyle(NULL), glyph(), 
-		PtransX(0.0f), PtransY(0.0f), PRot(0.0f), PDx(0.0f), embedded(NULL), ch() {}
+		PtransX(0.0f), PtransY(0.0f), PRot(0.0f), PDx(0.0f), embedded(NULL), marker(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), marker(other.marker), ch(other.ch)
 	{
 		glyph.more = NULL;
 		GlyphLayout *layout = &glyph;
Index: scribus/pageitem.h
===================================================================
--- scribus/pageitem.h	(wersja 17181)
+++ scribus/pageitem.h	(kopia robocza)
@@ -237,15 +237,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();
Index: scribus/pageitem.cpp
===================================================================
--- scribus/pageitem.cpp	(wersja 17181)
+++ scribus/pageitem.cpp	(kopia robocza)
@@ -41,6 +41,7 @@
 #include "cmsettings.h"
 #include "colorblind.h"
 #include "commonstrings.h"
+#include "markers.h"
 
 #include "pageitem_group.h"
 #include "pageitem_textframe.h"
@@ -825,6 +826,20 @@
 	isInlineImage = false;
 }
 
+PageItem::~PageItem()
+{
+	if (tempImageFile != NULL)
+		delete tempImageFile;
+	//delete markers pointed to that item
+	QMap<QString,Marker*>::Iterator markIt;
+	for (markIt = doc()->markersMap.begin(); markIt != doc()->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		if ((marker->getType() == MARKER2ItemType) && (marker->getItemPtr() == this))
+			doc()->eraseMarker(marker);
+	}
+}
+
 void PageItem::setXPos(const double newXPos, bool drawingOnly)
 {
 	Xpos = newXPos;
@@ -2223,6 +2238,15 @@
 		else
 			return "%";
 	}
+	//check for markers
+	else if (ch == SpecialChars::OBJECT)
+	{
+		ScText* hl = itemText.item(base);
+		if (hl->marker != NULL && hl->marker->getType() != MARKERAnchorType && hl->marker->getType() != MARKERIndexType)
+		{
+			chstr = hl->marker->getString();
+		}
+	}
 	return chstr;
 }
 
@@ -2406,6 +2430,12 @@
 			points.addQuadPoint(0, -10, 0, -10, 0, -6, 0, -6);
 			stroke = true;
 		}
+		else if (glyph == SpecialChars::OBJECT.unicode())
+		{
+			points.resize(0);
+			points.addQuadPoint(0, -8, 1, -8, 0, -6, 1, -6);
+			stroke = true;
+		}
 		else // ???
 		{
 			points.resize(0);
Index: scribus/scribusdoc.h
===================================================================
--- scribus/scribusdoc.h	(wersja 17181)
+++ scribus/scribusdoc.h	(kopia robocza)
@@ -40,6 +40,7 @@
 #include "scribusapi.h"
 #include "colormgmt/sccolormgmtengine.h"
 #include "documentinformation.h"
+#include "markers.h"
 #include "observable.h"
 #include "pageitem.h"
 #include "pagestructs.h"
@@ -72,7 +73,7 @@
 class ScPattern;
 class UndoTransaction;
 class Serializer;
-
+class MarkersManager;
 class QProgressBar;
 
 struct SCRIBUS_API NodeEditContext : public MassObservable<QPointF>
@@ -1259,7 +1260,7 @@
 	MassObservable<ScPage*> m_pagesChanged;
 	MassObservable<QRectF> m_regionsChanged;
 	DocUpdater* m_docUpdater;
-	
+
 signals:
 	//Lets make our doc talk to our GUI rather than confusing all our normal stuff
 	/**
@@ -1520,8 +1521,24 @@
 	void updatePict(QString name);
 	void updatePictDir(QString name);
 	void removePict(QString name);
-//welding two items
+// Markers
+public:
+	//list of markers with its lables as keys
+	QMap<QString, Marker*> markersMap;
+	Marker* getMarkerDefinied(QString label, MarkerType type); //returns marker with label and type (labels are unique only for same type markers)
+	PageItem* findMarker(Marker* marker, int &lastItem);
+	PageItem* findMarker(Marker* marker);
+	PageItem* findMarker(QString label, MarkerType type);
+	bool findMarkerCPos(Marker* marker, PageItem* &item, int &CPos);
+	bool eraseMarker(QString label, MarkerType type);
+	bool eraseMarker(Marker* marker);
+	void editMarkerDlg(Marker*);
+	void updateMarkerVariableText(Marker* marker, bool forceUpdate = false); //returns if any text was changed
 public slots:
+	void updateMarkers(); //update strings (page number) for markers pointed to anchors and items
+
+	//welding two items
+public slots:
 	void itemSelection_UnWeld();
 	void itemSelection_Weld();
 	void itemSelection_EditWeld();
Index: scribus/actionmanager.cpp
===================================================================
--- scribus/actionmanager.cpp	(wersja 17181)
+++ scribus/actionmanager.cpp	(kopia robocza)
@@ -240,8 +240,11 @@
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 	name="editJavascripts";
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	name="editMarkers";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 
 	(*scrActions)["editStyles"]->setToggleAction(true);
+	(*scrActions)["editMarkers"]->setToggleAction(true);
 
 	connect( (*scrActions)["editUndoAction"], SIGNAL(triggeredData(int)) , undoManager, SLOT(undo(int)) );
 	connect( (*scrActions)["editRedoAction"], SIGNAL(triggeredData(int)) , undoManager, SLOT(redo(int)) );
@@ -540,10 +543,45 @@
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 	(*scrActions)["stickyTools"]->setToggleAction(true);
 
+	//Markers
+	name="insertMarkerAnchor";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarkerVariableText";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarkerItem";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarker2Marker";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+//	name="insertMarkerFootnote";
+//	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+//	(*scrActions)[name]->setEnabled(true);
+//	name="insertMarkerEndnote";
+//	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+//	(*scrActions)[name]->setEnabled(true);
+//	name="insertMarkerIndex";
+//	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+//	(*scrActions)[name]->setEnabled(true);
+	name="editMarker";
+	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)["insertMarkerAnchor"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerAnchor()) );
+	connect( (*scrActions)["insertMarkerVariableText"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerVariableText()) );
+	connect( (*scrActions)["insertMarkerItem"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerItem()) );
+	connect( (*scrActions)["insertMarker2Marker"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarker2Marker()) );
+//	connect( (*scrActions)["insertMarkerFootnote"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerFootnote()) );
+//	connect( (*scrActions)["insertMarkerEndnote"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerEndnote()) );
+//	connect( (*scrActions)["insertMarkerIndex"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerIndex()) );
+	connect( (*scrActions)["editMarker"], SIGNAL(triggered()), mainWindow, SLOT(slotEditMarker()) );
 }
 
 void ActionManager::initPageMenuActions()
@@ -1391,6 +1429,7 @@
 //	(*scrActions)["editPatterns"]->setTexts( tr("Patterns..."));
 //	(*scrActions)["editGradients"]->setTexts( tr("Gradients..."));
 	(*scrActions)["editStyles"]->setTexts( tr("S&tyles..."));
+	(*scrActions)["editMarkers"]->setTexts( tr("Markers..."));
 	(*scrActions)["editMasterPages"]->setTexts( tr("&Master Pages..."));
 	(*scrActions)["editJavascripts"]->setTexts( tr("&JavaScripts..."));
 
@@ -1485,6 +1524,14 @@
 	(*scrActions)["insertGlyph"]->setTexts( tr("&Glyph..."));
 	(*scrActions)["insertSampleText"]->setTexts( tr("Sample Text"));
 	(*scrActions)["stickyTools"]->setTexts( tr("Sticky Tools"));
+	(*scrActions)["insertMarkerAnchor"]->setTexts( tr("Anchor Marker"));
+	(*scrActions)["insertMarkerVariableText"]->setTexts( tr("Variable Text"));
+	(*scrActions)["insertMarkerItem"]->setTexts( tr("Reference to Item"));
+	(*scrActions)["insertMarker2Marker"]->setTexts( tr("Reference to Anchor Marker"));
+//	(*scrActions)["insertMarkerFootnote"]->setTexts( tr("Footnote"));
+//	(*scrActions)["insertMarkerEndnote"]->setTexts( tr("Endnote"));
+//	(*scrActions)["insertMarkerIndex"]->setTexts( tr("Index entry"));
+	(*scrActions)["editMarker"]->setTexts( tr("Edit Marker"));
 
 	//Page menu
 	(*scrActions)["pageInsert"]->setTexts( tr("&Insert..."));
@@ -1873,6 +1920,7 @@
 		<< "editReplaceColors"
 //		<< "editPatterns"
 		<< "editStyles"
+		<< "editMarkers"
 		<< "editMasterPages"
 		<< "editJavascripts";
 	//Style
@@ -1978,7 +2026,15 @@
 		<< "toolsInsertRenderFrame"
 		<< "stickyTools"
 		<< "insertGlyph"
-		<< "insertSampleText";
+		<< "insertSampleText"
+		<< "insertMarkerAnchor"
+		<< "insertMarkerVariableText"
+		<< "insertMarkerItem"
+		<< "insertMarker2Marker"
+//		<< "insertMarkerFootnote"
+//		<< "insertMarkerEndnote"
+//		<< "insertMarkerIndex"
+		<< "editMarker";
 
 	itmenu->second
 		<< "unicodeSoftHyphen"
Index: scribus/pageitem_textframe.cpp
===================================================================
--- scribus/pageitem_textframe.cpp	(wersja 17181)
+++ scribus/pageitem_textframe.cpp	(kopia robocza)
@@ -34,7 +34,9 @@
 
 #include "canvas.h"
 #include "commonstrings.h"
+#include "fonts/scface.h"
 #include "hyphenator.h"
+#include "markers.h"
 #include "pageitem.h"
 #include "pageitem_group.h"
 #include "pageitem_textframe.h"
@@ -53,6 +55,12 @@
 #include "util.h"
 #include "util_math.h"
 
+#include "ui/markerinsertdlgbase.h"
+#include "ui/marker2item.h"
+#include "ui/marker2marker.h"
+#include "ui/markeranchor.h"
+#include "ui/markervariabletext.h"
+#include "ui/markersmanager.h"
 #include "ui/guidemanager.h"
 
 #include <cairo.h>
@@ -1392,6 +1400,15 @@
 		for (int a = firstInFrame(); a < itemText.length(); ++a)
 		{
 			hl = itemText.item(a);
+			if (hl->ch == SpecialChars::OBJECT && hl->marker != NULL)
+			{
+				hl->glyph.glyph = SpecialChars::OBJECT.unicode() + ScFace::CONTROL_GLYPHS;
+				if (hl->marker->getType() == MARKERAnchorType || hl->marker->getType() == MARKERIndexType)
+				{
+					hl->glyph.shrink();
+					continue;
+				}
+			}
 			if (a > 0 && itemText.text(a-1) == SpecialChars::PARSEP)
 				style = itemText.paragraphStyle(a);
 			if (current.itemsInLine == 0)
@@ -1525,8 +1542,12 @@
 				// 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 = charStyle.font().realCharHeight(chstr[0], 1);
-				double realCharAscent = charStyle.font().realCharAscent(chstr[0], 1);
+				double realCharHeight = 0.0, realCharAscent = 0.0;
+				for (int i = 0; i < chstr.length(); i++)
+				{
+					realCharHeight = qMax(realCharHeight, charStyle.font().realCharHeight(chstr[i], 1));
+					realCharAscent = qMax(realCharAscent, charStyle.font().realCharAscent(chstr[i], 1));
+				}
 				double fontAscent     = charStyle.font().ascent(style.charStyle().fontSize() / 10.0);
 				if (realCharHeight == 0.0)
 					realCharHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
@@ -1591,11 +1612,19 @@
 				}
 				else
 				{
-					double realCharHeight = charStyle.font().realCharHeight(chstr[0], charStyle.fontSize() / 10.0);
+					double realCharHeight = 0.0;
+					wide = 0.0; realAsce = 0.0;
+					//
+					for (int i = 0; i < chstr.length(); i++)
+					{
+						realCharHeight = qMax(realCharHeight, charStyle.font().realCharHeight(chstr[i], charStyle.fontSize() / 10.0));
+						realAsce = qMax(realAsce, charStyle.font().realCharHeight(chstr[i], chsd / 10.0));
+						wide += charStyle.font().realCharWidth(chstr[i], chsd / 10.0);
+					}
+					wide = (wide* scaleH) + (1 - scaleH);
+					realAsce = realAsce  * scaleV + offset;
 					if (realCharHeight == 0)
 						realCharHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
-					wide = (charStyle.font().realCharWidth(chstr[0], chsd / 10.0) * scaleH) + (1 - scaleH); //dropcaps are to close to next glyphs if glyphs are hard scaled
-					realAsce = charStyle.font().realCharHeight(chstr[0], chsd / 10.0) * scaleV + offset;
 					asce = charStyle.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;
@@ -1619,12 +1648,19 @@
 					desc = realDesc = 0;
 				else
 				{
+					for (int i = 0; i < chstr.length(); i++)
+					{
+						if (chstr[i] == SpecialChars::OBJECT)
+							continue;
+						realDesc = qMax(realDesc, charStyle.font().realCharDescent(chstr[i], hlcsize10));
+						realAsce = charStyle.font().realCharAscent(chstr[i], hlcsize10);
+					}
+					realDesc =  realDesc * scaleV - offset;
 					desc = -charStyle.font().descent(hlcsize10);
-					realDesc = charStyle.font().realCharDescent(chstr[0], hlcsize10) * scaleV - offset;
 					current.rememberShrinkStretch(hl->ch, wide, style);
 				}
 				asce = charStyle.font().ascent(hlcsize10);
-				realAsce = charStyle.font().realCharAscent(chstr[0], hlcsize10) * scaleV + offset;
+				realAsce = realAsce * scaleV + offset;
 			}
 
 			//check for Y position at beginning of line
@@ -1935,7 +1971,12 @@
 			
 			// remember y pos
 			if (DropCmode)
-				hl->glyph.yoffset -= charStyle.font().realCharHeight(chstr[0], chsd / 10.0) - charStyle.font().realCharAscent(chstr[0], chsd / 10.0);
+			{
+				double yoffset = 0.0;
+				for (int i = 0; i < chstr.length(); i++)
+					yoffset = qMax(yoffset, charStyle.font().realCharHeight(chstr[i], chsd / 10.0) - charStyle.font().realCharAscent(chstr[i], chsd / 10.0));
+				hl->glyph.yoffset -= yoffset;
+			}
 			
 			// remember x pos
 			double breakPos = current.xPos;
@@ -2770,11 +2811,13 @@
 			{
 				bool selecteds = itemText.selected(as);
 				hls = itemText.item(as);
+				if (hls->marker != NULL && (hls->marker->getType() == MARKERAnchorType || hls->marker->getType() == MARKERIndexType))
+					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()) && (hls->ch == SpecialChars::OBJECT && hls->embedded.hasItem()))
 					    || previousWasObject)
 					{
 						sFList << selectedFrame;
@@ -4030,3 +4073,231 @@
 {
 	invalidateLayout();
 }
+
+void PageItem_TextFrame::insertMarkerDlg(MarkerType markerType)
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	QVector<Marker*> markerList;
+	for (markIt = m_Doc->markersMap.begin(); markIt != m_Doc->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		markerList.push_back(marker);
+	}
+	MarkerInsertDlg* insertMDialog = NULL;
+	switch (markerType)
+	{
+	case MARKERAnchorType:
+		insertMDialog = (MarkerInsertDlg*) new MarkerAnchorDlg(m_Doc->scMW());
+		break;
+	case MARKERVariableTextType:
+		insertMDialog = (MarkerInsertDlg*) new MarkerVariableTextDlg(markerList, true, m_Doc->scMW());
+		break;
+	case MARKER2ItemType:
+		insertMDialog = (MarkerInsertDlg*) new Marker2ItemDlg(m_Doc->scMW());
+		break;
+	case MARKER2MarkerType:
+		insertMDialog = (MarkerInsertDlg*) new Marker2MarkerDlg(markerList, NULL, m_Doc->scMW());
+		break;
+	case MARKERFootnoteType:
+		break;
+	case MARKEREndnoteType:
+		break;
+	case MARKERIndexType:
+		break;
+	}
+	if (insertMDialog == NULL)
+	{
+		qDebug() << "Dialog not implemented for markers type " << markerType;
+		return;
+	}
+	insertMDialog->setWindowTitle(tr("Insert new ") + insertMDialog->windowTitle());
+	if (insertMDialog->exec())
+	{
+		Marker* Mrk = NULL;
+		MarkerData d;
+		 d.strPtr = NULL;
+		 d.itemPtr = NULL;
+		 d.mrkPtr = NULL;
+		QString label = "", text = "";
+		switch (markerType)
+		{
+		case MARKERAnchorType:
+			//only gets label for new marker
+			insertMDialog->values(label);
+			if (label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.itemPtr = this;
+			break;
+		case MARKERVariableTextType:
+			Mrk = insertMDialog->values(label, text);
+			if ((Mrk == NULL) && (label.isEmpty() || text.isEmpty()))
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.strPtr = new QString(text);
+			break;
+		case MARKER2ItemType:
+			insertMDialog->values(label, d.itemPtr);
+			if (d.itemPtr == NULL || label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.strPtr = new QString(QString::number(d.itemPtr->OwnPage +1));
+			break;
+		case MARKER2MarkerType:
+			//gets pointer to referenced marker
+			insertMDialog->values(label, d.mrkPtr);
+			if (d.mrkPtr == NULL || label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.strPtr = new QString(QString::number(d.mrkPtr->OwnPage +1));
+		case MARKERFootnoteType:
+			break;
+		case MARKEREndnoteType:
+			break;
+		case MARKERIndexType:
+			break;
+		}
+		//check if marker with such label exist already
+		if (markerType != MARKERVariableTextType && m_Doc->getMarkerDefinied(label, markerType) != NULL)
+			return; //FIX ME here user should be warned that inserting of marker fails and why
+
+		if (Mrk == NULL)
+		{
+			Mrk = new Marker;
+			Mrk->setValues(label, OwnPage, markerType, d);
+			m_Doc->markersMap.insert(label,Mrk);
+		}
+		else
+		{ // that must be variable text marker
+			Mrk->setStrPtr(d.strPtr);
+			m_Doc->updateMarkerVariableText(Mrk, true);
+		}
+		itemText.insertMarker(Mrk);
+		Mrk->OwnPage = OwnPage;
+		update();
+		m_Doc->changed();
+	}
+	delete insertMDialog;
+	m_Doc->scMW()->markersManager->updateListView();
+}
+
+void PageItem_TextFrame::editMarkerDlg(Marker * marker)
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	QVector<Marker*> markerList;
+	for(markIt = m_Doc->markersMap.begin(); markIt != m_Doc->markersMap.end(); ++markIt)
+	{
+		Marker* mark = markIt.value();
+		markerList.push_back(mark);
+	}
+	MarkerInsertDlg* editMDialog = NULL;
+	switch (marker->getType())
+	{
+	case MARKERAnchorType:
+		editMDialog = (MarkerInsertDlg*) new MarkerAnchorDlg(m_Doc->scMW());
+		editMDialog->setValues(marker->label);
+		break;
+	case MARKERVariableTextType:
+		editMDialog = (MarkerInsertDlg*) new MarkerVariableTextDlg(markerList, true, m_Doc->scMW());
+		editMDialog->setValues(marker->label, marker->getString());
+		break;
+	case MARKER2ItemType:
+		editMDialog = (MarkerInsertDlg*) new Marker2ItemDlg(m_Doc->scMW());
+		editMDialog->setValues(marker->label, marker->getItemPtr());
+		break;
+	case MARKER2MarkerType:
+		editMDialog = (MarkerInsertDlg*) new Marker2MarkerDlg(markerList, marker, m_Doc->scMW());
+		editMDialog->setValues(marker->label, marker->getMarker());
+		break;
+	case MARKERFootnoteType:
+		break;
+	case MARKEREndnoteType:
+		break;
+	case MARKERIndexType:
+		break;
+	default:
+		break;
+	}
+	editMDialog->setWindowTitle(tr("Edit ") + editMDialog->windowTitle());
+	if (editMDialog->exec())
+	{
+		Marker* Mrk = NULL;
+		MarkerData d;
+		 d.strPtr = NULL;
+		 d.itemPtr = NULL;
+		 d.mrkPtr = NULL;
+		 d.itemName = "";
+		QString label = "", text = "";
+		QString oldStr = marker->getString();
+		switch (marker->getType())
+		{
+		case MARKERAnchorType:
+			//only gets label for new marker
+			editMDialog->values(label);
+			if (label.isEmpty() || m_Doc->getMarkerDefinied(label, MARKERAnchorType) != NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			marker->label = label;
+			break;
+		case MARKERVariableTextType:
+			Mrk = editMDialog->values(label, text);
+			if ((Mrk == NULL) && (label.isEmpty() || text.isEmpty()))
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (Mrk != NULL)
+			{
+				if (Mrk != marker)
+				{
+					ScText* hl = itemText.item(itemText.cursorPosition());
+					hl->marker = Mrk;
+					marker = Mrk;
+				}
+				marker->label = label;
+				if (text != oldStr)
+				{
+					marker->setString(text);
+					if (marker->getString() != oldStr)
+						m_Doc->updateMarkerVariableText(marker, true);
+				}
+			}
+			else
+			{
+				d.strPtr = new QString(text);
+				Mrk = new Marker;
+				Mrk->setValues(label, OwnPage, MARKERVariableTextType, d);
+				m_Doc->markersMap.insert(label,Mrk);
+				ScText* hl = itemText.item(itemText.cursorPosition());
+				hl->marker = Mrk;
+			}
+			break;
+		case MARKER2ItemType:
+			editMDialog->values(label, d.itemPtr);
+			if (label.isEmpty() || d.itemPtr == NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.itemPtr != marker->getItemPtr())
+			{
+				marker->setItemPtr(d.itemPtr);
+				marker->setString(QString("%1").arg(d.itemPtr->OwnPage +1));
+			}
+			marker->label = label;
+			break;
+		case MARKER2MarkerType:
+			//gets pointer to referenced marker
+			editMDialog->values(label, d.mrkPtr);
+			if ((d.mrkPtr == NULL) && label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.mrkPtr != marker->getMarker())
+			{
+				marker->setMarker(d.mrkPtr);
+				marker->setString(QString("%1").arg(d.mrkPtr->OwnPage +1));
+			}
+			marker->label = label;
+		case MARKERFootnoteType:
+			break;
+		case MARKEREndnoteType:
+			break;
+		case MARKERIndexType:
+			break;
+		default:
+			break;
+		}
+		update();
+		m_Doc->changed();
+		m_Doc->scMW()->markersManager->updateListView();
+	}
+	delete editMDialog;
+}
Index: scribus/ui/markersmanager.ui
===================================================================
--- scribus/ui/markersmanager.ui	(wersja 0)
+++ scribus/ui/markersmanager.ui	(wersja 0)
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MarkersManager</class>
+ <widget class="QDialog" name="MarkersManager">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>253</width>
+    <height>249</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>200</width>
+    <height>100</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <property name="modal">
+   <bool>false</bool>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QListWidget" name="listView">
+     <property name="editTriggers">
+      <set>QAbstractItemView::DoubleClicked</set>
+     </property>
+     <property name="showDropIndicator" stdset="0">
+      <bool>false</bool>
+     </property>
+     <property name="selectionMode">
+      <enum>QAbstractItemView::NoSelection</enum>
+     </property>
+     <property name="selectionBehavior">
+      <enum>QAbstractItemView::SelectItems</enum>
+     </property>
+     <property name="horizontalScrollMode">
+      <enum>QAbstractItemView::ScrollPerPixel</enum>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QPushButton" name="UpdateButton">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="text">
+      <string>Update All Markers</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QSplitter" name="splitter">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <widget class="QPushButton" name="EditButton">
+      <property name="text">
+       <string>Edit</string>
+      </property>
+     </widget>
+     <widget class="QPushButton" name="DeleteButton">
+      <property name="text">
+       <string>Delete</string>
+      </property>
+     </widget>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
Index: scribus/ui/marker2marker.ui
===================================================================
--- scribus/ui/marker2marker.ui	(wersja 0)
+++ scribus/ui/marker2marker.ui	(wersja 0)
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Marker2MarkerDlg</class>
+ <widget class="QDialog" name="Marker2MarkerDlg">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>362</width>
+    <height>103</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>0</width>
+    <height>103</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>103</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QSplitter" name="splitter">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <widget class="QLabel" name="label_2">
+      <property name="text">
+       <string>Label:</string>
+      </property>
+     </widget>
+     <widget class="QLineEdit" name="labelEdit"/>
+    </widget>
+   </item>
+   <item>
+    <widget class="QSplitter" name="splitter_2">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <widget class="QLabel" name="label">
+      <property name="text">
+       <string>Select marker:</string>
+      </property>
+     </widget>
+     <widget class="QComboBox" name="LabelList">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="editable">
+       <bool>false</bool>
+      </property>
+      <property name="currentIndex">
+       <number>-1</number>
+      </property>
+      <property name="duplicatesEnabled">
+       <bool>false</bool>
+      </property>
+     </widget>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>166</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="buttonBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>Marker2MarkerDlg</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>262</x>
+     <y>90</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>174</x>
+     <y>54</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>Marker2MarkerDlg</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>262</x>
+     <y>90</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>174</x>
+     <y>54</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
Index: scribus/ui/markerinsertdlgbase.h
===================================================================
--- scribus/ui/markerinsertdlgbase.h	(wersja 0)
+++ scribus/ui/markerinsertdlgbase.h	(wersja 0)
@@ -0,0 +1,39 @@
+#ifndef MARKERINSERTDLG_H
+#define MARKERINSERTDLG_H
+
+#include <QDialog>
+#include <scribusapi.h>
+
+class NotesSet;
+class Marker;
+class PageItem;
+
+class SCRIBUS_API MarkerInsertDlg : public QDialog
+{
+	Q_OBJECT
+
+public:
+	MarkerInsertDlg(const QVector<Marker*>&, QWidget *parent = 0) : QDialog(parent) {}
+	MarkerInsertDlg(const QList<NotesSet*>&, QWidget *parent = 0) : QDialog(parent) {}
+	MarkerInsertDlg(QWidget *parent = 0) : QDialog(parent) {}
+	~MarkerInsertDlg() {}
+
+	virtual void values(QString &label) {}
+	virtual void values(QString &label, PageItem* &item) {}
+	virtual Marker* values(QString& label, QString& text) { return NULL; }
+	virtual void values(QString& label, Marker* &marker) {}
+	virtual NotesSet* values() { return NULL; }
+
+	virtual void setValues(const QString label) {}
+	virtual void setValues(const QString label, const QString text) {}
+	virtual void setValues(const QString label, const PageItem* ptr) {}
+	virtual void setValues(const QString label, const Marker* ptr) {}
+	virtual void setValues(const NotesSet* defaultSet) {}
+	
+signals:
+
+public slots:
+
+};
+
+#endif // MARKERINSERTDLG_H
Index: scribus/ui/markervariabletext.ui
===================================================================
--- scribus/ui/markervariabletext.ui	(wersja 0)
+++ scribus/ui/markervariabletext.ui	(wersja 0)
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MarkerVariableTextDlg</class>
+ <widget class="QDialog" name="MarkerVariableTextDlg">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>394</width>
+    <height>117</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>0</width>
+    <height>117</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>117</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Add new Marker for Variable Text</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QHBoxLayout" name="labelLayout">
+     <item>
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Label:</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Text to insert:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="textEdit"/>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>202</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="buttonBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>MarkerVariableTextDlg</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>MarkerVariableTextDlg</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
Index: scribus/ui/marker2item.ui
===================================================================
--- scribus/ui/marker2item.ui	(wersja 0)
+++ scribus/ui/marker2item.ui	(wersja 0)
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Marker2ItemDlg</class>
+ <widget class="QDialog" name="Marker2ItemDlg">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>349</width>
+    <height>102</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>115</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <layout class="QFormLayout" name="formLayout">
+     <property name="fieldGrowthPolicy">
+      <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+     </property>
+     <item row="0" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Label:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QLineEdit" name="labelEdit"/>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Item:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QComboBox" name="ItemList">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="editable">
+        <bool>false</bool>
+       </property>
+       <property name="currentIndex">
+        <number>-1</number>
+       </property>
+       <property name="duplicatesEnabled">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="1" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>164</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="buttonBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>Marker2ItemDlg</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>262</x>
+     <y>90</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>174</x>
+     <y>54</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>Marker2ItemDlg</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>262</x>
+     <y>90</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>174</x>
+     <y>54</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
Index: scribus/ui/markeranchor.ui
===================================================================
--- scribus/ui/markeranchor.ui	(wersja 0)
+++ scribus/ui/markeranchor.ui	(wersja 0)
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MarkerAnchorDlg</class>
+ <widget class="QDialog" name="MarkerAnchorDlg">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>81</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>0</width>
+    <height>81</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>81</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Label:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1">
+    <widget class="QLineEdit" name="labelEdit"/>
+   </item>
+   <item row="1" column="1">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>MarkerAnchorDlg</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>MarkerAnchorDlg</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
Index: scribus/ui/contextmenu.cpp
===================================================================
--- scribus/ui/contextmenu.cpp	(wersja 17181)
+++ scribus/ui/contextmenu.cpp	(kopia robocza)
@@ -94,6 +94,7 @@
 	QMenu *menuLayer = new QMenu(this);
 	QMenu *menuLevel = new QMenu(this);
 	QMenu *menuPDF = new QMenu(this);
+	QMenu *menuMarker = new QMenu(this);
 	QMenu *menuResolution = new QMenu(this);
 //	QMenu *menuWeld = new QMenu(this);
 	
@@ -172,6 +173,25 @@
 			addAction(m_AP->scrActions["fileImportAppendText"]);
 			addAction(m_AP->scrActions["toolsEditWithStoryEditor"]);
 			addAction(m_AP->scrActions["insertSampleText"]);
+			if (m_doc->appMode == modeEdit)
+			{
+				QAction *act2 = addMenu(menuMarker);
+				act2->setText( ScribusView::tr("Insert Marker"));
+				menuMarker->addAction(m_AP->scrActions["insertMarkerAnchor"]);
+				menuMarker->addAction(m_AP->scrActions["insertMarkerVariableText"]);
+				menuMarker->addAction(m_AP->scrActions["insertMarkerItem"]);
+				menuMarker->addAction(m_AP->scrActions["insertMarker2Marker"]);
+//				menuMarker->addAction(m_AP->scrActions["insertMarkerFootnote"]);
+//				menuMarker->addAction(m_AP->scrActions["insertMarkerEndnote"]);
+//				menuMarker->addAction(m_AP->scrActions["insertMarkerIndex"]);
+				if (currItem->itemText.cursorPosition() < currItem->itemText.length())
+				{
+					ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+					if (hl->ch == SpecialChars::OBJECT && hl->marker != NULL)
+						addAction(m_AP->scrActions["editMarker"]);
+				}
+
+			}
 		}
 		else //enable this for, eg, text on a path
 			if (m_actionList.contains("toolsEditWithStoryEditor"))
Index: scribus/text/storytext.cpp
===================================================================
--- scribus/text/storytext.cpp	(wersja 17181)
+++ scribus/text/storytext.cpp	(kopia robocza)
@@ -329,10 +329,13 @@
 		if ((it->ch == SpecialChars::PARSEP)) {
 			removeParSep(i);
 		}
+		Marker* mrk = it->marker;
 //		qDebug("remove char %d at %d", (int) it->ch.unicode(), i);
 		d->takeAt(i);
 		d->len--;
 		delete it;
+		if ((mrk != NULL) && mrk->isUnique())
+			doc->eraseMarker(mrk);
 		// #9592 : adjust selFirst and selLast, those values have to be
 		// consistent in functions such as select()
 		if (i <= selLast) --selLast;
@@ -477,6 +480,15 @@
 	invalidate(pos, pos + 1);
 }
 
+void StoryText::insertMarker(Marker* M, int pos)
+{
+	if (pos < 0)
+		pos = d->cursorPosition;
+
+	insertChars(pos, SpecialChars::OBJECT);
+	const_cast<StoryText *>(this)->d->at(pos)->marker = M;
+}
+
 void StoryText::hyphenateWord(int pos, uint len, char* hyphens)
 {
 	assert(pos >= 0);
Index: scribus/text/storytext.h
===================================================================
--- scribus/text/storytext.h	(wersja 17181)
+++ scribus/text/storytext.h	(kopia robocza)
@@ -126,6 +126,8 @@
 	// Insert object at specific position
  	void insertObject(int pos, PageItem* obj);
  	void replaceChar(int pos, QChar ch);
+	// Insert marker at cursor or specific position
+	void insertMarker(Marker* M, int pos = -1);
 
 	void hyphenateWord(int pos, uint len, char* hyphens);
 	
Index: scribus/scribus.cpp
===================================================================
--- scribus/scribus.cpp	(wersja 17181)
+++ scribus/scribus.cpp	(kopia robocza)
@@ -99,6 +99,7 @@
 #include "gtgettext.h"
 #include "hyphenator.h"
 #include "langmgr.h"
+#include "markers.h"
 #include "pageitem_group.h"
 #include "pageitem_imageframe.h"
 #include "pageitem_latexframe.h"
@@ -163,6 +164,8 @@
 #include "ui/loremipsum.h"
 #include "ui/marginwidget.h"
 #include "ui/margindialog.h"
+#include "ui/markerinsertdlgbase.h"
+#include "ui/markersmanager.h"
 #include "ui/masterpagepalette.h"
 #include "ui/mergedoc.h"
 #include "ui/movepage.h"
@@ -582,6 +585,12 @@
 	connect( styleManager, SIGNAL(paletteShown(bool)), scrActions["editStyles"], SLOT(setChecked(bool)));
 	styleManager->installEventFilter(this);
 
+	// initializing marker`s manager
+	markersManager = new MarkersManager(this, "markersManager");
+	connect( scrActions["editMarkers"], SIGNAL(toggled(bool)), markersManager, SLOT(setPaletteShown(bool)) );
+	connect( markersManager, SIGNAL(paletteShown(bool)), scrActions["editMarkers"], SLOT(setChecked(bool)));
+	markersManager->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)));
@@ -721,6 +730,7 @@
 //	scrMenuMgr->addMenuItem(scrActions["editGradients"], "Edit", false);
 //	scrMenuMgr->addMenuItem(scrActions["editPatterns"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editStyles"], "Edit", false);
+	scrMenuMgr->addMenuItem(scrActions["editMarkers"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editMasterPages"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editJavascripts"], "Edit", false);
 	scrMenuMgr->setMenuEnabled("EditPasteRecent", false);
@@ -837,6 +847,8 @@
 	scrMenuMgr->addMenuItem(scrActions["itemWeld"], "Item", false);
 	scrMenuMgr->addMenuItem(scrActions["itemEditWeld"], "Item", false);
 
+	scrMenuMgr->addMenuItem(scrActions["editMarker"], "Item", false);
+
 	//Insert menu
 	scrMenuMgr->createMenu("Insert", ActionManager::defaultMenuNameEntryTranslated("Insert"));
 	scrMenuMgr->addMenuItem(scrActions["insertFrame"], "Insert", false);
@@ -927,6 +939,15 @@
 
 	scrMenuMgr->addMenuSeparator("Insert");
 	scrMenuMgr->addMenuItem(scrActions["insertSampleText"], "Insert", false);
+	scrMenuMgr->addMenuSeparator("Insert");
+	scrMenuMgr->createMenu("InsertMarker", tr("Markers"), "Insert");
+	scrMenuMgr->addMenuItem(scrActions["insertMarkerAnchor"], "InsertMarker", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarkerVariableText"], "InsertMarker", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarkerItem"], "InsertMarker", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarker2Marker"], "InsertMarker", false);
+//	scrMenuMgr->addMenuItem(scrActions["insertMarkerFootnote"], "InsertMarker", false);
+//	scrMenuMgr->addMenuItem(scrActions["insertMarkerEndnote"], "InsertMarker", false);
+//	scrMenuMgr->addMenuItem(scrActions["insertMarkerIndex"], "InsertMarker", false);
 
 	//Page menu
 	scrMenuMgr->createMenu("Page", ActionManager::defaultMenuNameEntryTranslated("Page"));
@@ -1129,6 +1150,7 @@
 //AV to be replaced with Selection::update and listener in PropertiesPalette
 void ScribusMainWindow::setTBvals(PageItem *currItem)
 {
+	scrActions["editMarker"]->setEnabled(false);
 	if (currItem->itemText.length() != 0)
 	{
 //		int ChPos = qMin(currItem->CPos, static_cast<int>(currItem->itemText.length()-1));
@@ -1142,6 +1164,11 @@
 		emit TextStyle(doc->currentStyle);
 		// to go: (av)
 		propertiesPalette->textPal->updateStyle(doc->currentStyle);
+		if (doc->appMode == modeEdit && currItem->itemText.cursorPosition() < currItem->itemText.length())
+		{
+			ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+			scrActions["editMarker"]->setEnabled((hl->ch == SpecialChars::OBJECT && hl->marker != NULL));
+		}
 	}
 }
 
@@ -1984,6 +2011,7 @@
 		tempView->cmsToolbarButton->setChecked(tempDoc->HasCMS);
 		undoManager->switchStack(tempDoc->DocName);
 		styleManager->setDoc(tempDoc);
+		markersManager->setDoc(tempDoc);
 		tocGenerator->setDoc(tempDoc);
 	}
 	undoManager->setUndoEnabled(true);
@@ -2227,6 +2255,7 @@
 	docCheckerPalette->setDoc(doc);
 	tocGenerator->setDoc(doc);
 	styleManager->setDoc(doc);
+	markersManager->setDoc(doc);
 	symbolPalette->setDoc(doc);
 	modeToolBar->Angle->setValue(doc->itemToolPrefs().calligrapicPenAngle);
 	modeToolBar->PWidth->setValue(doc->itemToolPrefs().calligrapicPenWidth);
@@ -2258,6 +2287,7 @@
 	updateActiveWindowCaption(doc->DocName);
 // 	scrActions["shade100"]->setChecked(true);
 	propertiesPalette->setDoc(doc);
+	markersManager->setDoc(doc);
 	//propertiesPalette->Cpal->displayGradient(0);
 	pagePalette->setView(view);
 	layerPalette->setDoc(doc);
@@ -2397,6 +2427,7 @@
 //	scrActions["editPatterns"]->setEnabled(true);
 //	scrActions["editGradients"]->setEnabled(true);
  	scrActions["editStyles"]->setEnabled(true);
+	scrActions["editMarkers"]->setEnabled(true);
 	scrActions["editMasterPages"]->setEnabled(true);
 	scrActions["editJavascripts"]->setEnabled(true);
 
@@ -2463,6 +2494,7 @@
 	updateActiveWindowCaption(doc->DocName);
 // 	scrActions["shade100"]->setChecked(true);
 	propertiesPalette->setDoc(doc);
+	markersManager->setDoc(doc);
 	symbolPalette->setDoc(doc);
 //	propertiesPalette->Cpal->displayGradient(0);
 //	propertiesPalette->updateColorList();
@@ -2816,6 +2848,16 @@
 		scrActions["toolsCopyProperties"]->setEnabled(true);
 		scrActions["toolsEditWithStoryEditor"]->setEnabled(true);
 		scrActions["insertSampleText"]->setEnabled(true);
+		scrMenuMgr->setMenuEnabled("InsertMarker",true);
+		scrActions["insertMarkerAnchor"]->setEnabled(true);
+		scrActions["insertMarkerVariableText"]->setEnabled(true);
+		scrActions["insertMarkerItem"]->setEnabled(true);
+		scrActions["insertMarker2Marker"]->setEnabled(true);
+//		scrActions["insertMarkerFootnote"]->setEnabled(true);
+//		scrActions["insertMarkerEndnote"]->setEnabled(true);
+//		scrActions["insertMarkerIndex"]->setEnabled(true);
+		scrActions["editMarker"]->setEnabled(false);
+
 		if ((currItem->nextInChain() != 0) || (currItem->prevInChain() != 0))
 		{
 			scrActions["itemConvertToBezierCurve"]->setEnabled(false);
@@ -2844,6 +2886,8 @@
 			setTBvals(currItem);
 			scrActions["editSelectAll"]->setEnabled(true);
 			scrActions["editSelectAllOnLayer"]->setEnabled(false);
+			scrActions["insertSampleText"]->setEnabled(true);
+			scrMenuMgr->setMenuEnabled("InsertMarker",true);
 			charPalette->setEnabled(true, currItem);
 			if (currItem->asTextFrame())
 				enableTextActions(&scrActions, true, currItem->currentStyle().charStyle().font().scName());
@@ -2852,6 +2896,7 @@
 		}
 		else
 		{
+			scrMenuMgr->setMenuEnabled("InsertMarker",false);
 			doc->currentStyle = currItem->itemText.defaultStyle();
 			propertiesPalette->textPal->displayParStyle(doc->currentStyle.parent());
 			propertiesPalette->textPal->displayCharStyle(doc->currentStyle.charStyle().parent());
@@ -3204,6 +3249,7 @@
 //		scanDocument();
 //		docCheckerPalette->buildErrorList(doc);
 //	}
+//	doc->updateMarkers();
 	if (!doc->isModified())
 		doc->setModified(true);
 	updateActiveWindowCaption(doc->DocName + "*");
@@ -4185,6 +4231,7 @@
 			view->DrawNew();
 			slotDocCh();
 			styleManager->setDoc(doc);
+			markersManager->setDoc(doc);
 		}
 	}
 }
@@ -4585,6 +4632,7 @@
 //		scrActions["editPatterns"]->setEnabled(false);
 //		scrActions["editGradients"]->setEnabled(false);
 		scrActions["editStyles"]->setEnabled(false);
+		scrActions["editMarkers"]->setEnabled(false);
 		scrActions["editSearchReplace"]->setEnabled(false);
 		scrActions["editMasterPages"]->setEnabled(false);
 		scrActions["editJavascripts"]->setEnabled(false);
@@ -4690,6 +4738,7 @@
 	charPalette->setDoc(0);
 	tocGenerator->setDoc(0);
 	styleManager->setDoc(0);
+	markersManager->setDoc(0);
 	layerPalette->ClearInhalt();
 	docCheckerPalette->buildErrorList(0);
 	HaveDoc--;
@@ -5073,6 +5122,7 @@
 				styleManager->setDoc(doc);
 				propertiesPalette->unsetDoc();
 				propertiesPalette->setDoc(doc);
+				markersManager->setDoc(doc);
 				symbolPalette->unsetDoc();
 				symbolPalette->setDoc(doc);
 
@@ -5154,6 +5204,7 @@
 				styleManager->setDoc(doc);
 				propertiesPalette->unsetDoc();
 				propertiesPalette->setDoc(doc);
+				markersManager->setDoc(doc);
 				symbolPalette->unsetDoc();
 				symbolPalette->setDoc(doc);
 
@@ -6429,8 +6480,8 @@
 //					view->requestMode(modeEditClip);
 //					return;
 //				}
+				currItem->itemText.setCursorPosition(0);
 				setTBvals(currItem);
-				currItem->itemText.setCursorPosition(0);
 			}
 			scrActions["editPaste"]->setEnabled(false);
 			charPalette->setEnabled(true, currItem);
@@ -7771,6 +7822,7 @@
 	guidePalette->startup();
 	charPalette->startup();
 	styleManager->startup();
+	markersManager->startup();
 	symbolPalette->startup();
 
 	// init the toolbars
@@ -10050,6 +10102,7 @@
 	scrMenuMgr->setMenuEnabled("InsertQuote", enabled);
 	scrMenuMgr->setMenuEnabled("InsertSpace", enabled);
 	scrMenuMgr->setMenuEnabled("InsertLigature", enabled);
+	scrMenuMgr->setMenuEnabled("InsertMarker", enabled);
 }
 
 void ScribusMainWindow::updateTableMenuActions()
@@ -10081,4 +10134,76 @@
 	scrActions["tableAdjustFrameToTable"]->setEnabled(table);
 	scrActions["tableAdjustTableToFrame"]->setEnabled(table);
 }
+void ScribusMainWindow::insertMarker(MarkerType mType)
+{
+	if (HaveDoc && doc->m_Selection->itemAt(0)->isTextFrame() && doc->appMode == modeEdit)
+	{
+		doc->m_Selection->itemAt(0)->asTextFrame()->insertMarkerDlg(mType);
+		update();
+	}
+}
 
+void ScribusMainWindow::slotEditMarker()
+{
+	if (HaveDoc && doc->m_Selection->itemAt(0)->isTextFrame() && doc->appMode == modeEdit)
+	{
+		PageItem * currItem = doc->m_Selection->itemAt(0);
+		if (currItem->itemText.cursorPosition() < currItem->itemText.length())
+		{
+			ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+			if (hl->ch == SpecialChars::OBJECT && hl->marker != NULL)
+			{
+				currItem->asTextFrame()->editMarkerDlg(hl->marker);
+				slotUpdateMarkers();
+			}
+		}
+	}
+}
+
+void ScribusMainWindow::slotUpdateMarkers()
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	for(markIt = doc->markersMap.begin(); markIt != doc->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		int itemIndex = -1;
+		PageItem* item = doc->findMarker(marker, itemIndex);
+		while (item != NULL)
+		{
+			QString iName = item->getUName();
+			int cpos = -1;
+			if (doc->findMarkerCPos(marker, item, cpos))
+			{
+				ScText *hl = item->itemText.item(cpos);
+				if (hl->ch != SpecialChars::OBJECT || hl->marker == NULL)
+					continue;
+				if (hl->marker->getType() == marker->getType() && hl->marker->label == marker->label)
+				{
+					if (marker->getType() != MARKERVariableTextType)
+					{
+						marker->OwnPage = item->OwnPage;
+						if (marker->getType() == MARKER2ItemType)
+						{
+							PageItem* it = marker->getItemPtr();
+							if (it != NULL)
+								marker->setString(QString("%1").arg(it->OwnPage +1));
+							else
+								marker->setString("");
+						}
+						else if (marker->getType() == MARKER2MarkerType)
+						{
+							Marker* m = marker->getMarker();
+							if (m != NULL)
+								marker->setString(QString("%1").arg(m->OwnPage +1));
+							else
+								marker->setString("");
+						}
+					}
+					item->update();
+				}
+			}
+			item = doc->findMarker(marker,itemIndex);
+		}
+	}
+	doc->regionsChanged()->update(QRectF());
+}
Index: scribus/pageitem_textframe.h
===================================================================
--- scribus/pageitem_textframe.h	(wersja 17181)
+++ scribus/pageitem_textframe.h	(kopia robocza)
@@ -29,6 +29,7 @@
 
 #include "scribusapi.h"
 #include "pageitem.h"
+#include "markers.h"
 
 class ScPainter;
 class ScribusDoc;
@@ -117,6 +118,9 @@
 	
 private slots:
 	void slotInvalidateLayout();
+public:
+	void insertMarkerDlg(MarkerType mT = MARKERAnchorType);
+	void editMarkerDlg(Marker * marker);
 };
 
 #endif
Index: scribus/plugins/scriptplugin/scriptercore.cpp
===================================================================
--- scribus/plugins/scriptplugin/scriptercore.cpp	(wersja 17181)
+++ scribus/plugins/scriptplugin/scriptercore.cpp	(kopia robocza)
@@ -18,6 +18,7 @@
 
 #include "runscriptdialog.h"
 #include "ui/helpbrowser.h"
+#include "ui/markersmanager.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
@@ -151,6 +152,7 @@
 	if (ScMW->HaveDoc)
 	{
 		ScMW->propertiesPalette->setDoc(ScMW->doc);
+		ScMW->markersManager->setDoc(ScMW->doc);
 		ScMW->layerPalette->setDoc(ScMW->doc);
 		ScMW->outlinePalette->setDoc(ScMW->doc);
 		ScMW->outlinePalette->BuildTree();
Index: scribus/plugins/fileloader/scribus150format/scribus150format.h
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format.h	(wersja 17181)
+++ scribus/plugins/fileloader/scribus150format/scribus150format.h	(kopia robocza)
@@ -122,7 +122,13 @@
 		bool readPrinterOptions(ScribusDoc* doc, ScXmlStreamReader& reader);
 		bool readSections(ScribusDoc* doc, ScXmlStreamReader& reader);
 		bool readTableOfContents(ScribusDoc* doc, ScXmlStreamReader& reader);
+		bool readMarkers(ScribusDoc* doc, ScXmlStreamReader& reader);
 
+		//lists of items and markers with names only, which need update to pointers
+		QMap<QString, Marker*> markeredItemsList;
+		QMap<Marker*, QMap<QString, MarkerType> > markeredMarkersList;
+		void updateMarkersPtr(); //after document load items pointers should be updated in markeredItemList
+
 		PageItem* pasteItem(ScribusDoc *doc, ScXmlStreamAttributes& attrs, const QString& baseDir, int pagenr = -2 /* currentPage*/);
 
 		void writeCheckerProfiles(ScXmlStreamWriter& docu);
@@ -148,6 +154,7 @@
 		void writePdfOptions(ScXmlStreamWriter& docu);
 		void writeDocItemAttributes(ScXmlStreamWriter& docu);
 		void writeTOC(ScXmlStreamWriter& docu);
+		void writeMarkers(ScXmlStreamWriter & docu);
 		void writePageSets(ScXmlStreamWriter& docu);
 		void writeSections(ScXmlStreamWriter& docu);
 		void writePatterns(ScXmlStreamWriter& docu, const QString& baseDir, bool part = false, Selection* selection = 0);
Index: scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp	(wersja 17181)
+++ scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp	(kopia robocza)
@@ -389,6 +389,7 @@
 	writePdfOptions(docu);
 	writeDocItemAttributes(docu);
 	writeTOC(docu);
+	writeMarkers(docu);
 	writePageSets(docu);
 	writeSections(docu);
 	writePatterns(docu, fileDir);
@@ -1053,6 +1054,35 @@
 	docu.writeEndElement();
 }
 
+void Scribus150Format::writeMarkers(ScXmlStreamWriter & docu)
+{
+	//write list of definied markers to SLA
+	docu.writeStartElement("Markers");
+	QMap<QString,Marker*>::Iterator markIt;
+	for(markIt = m_Doc->markersMap.begin(); markIt != m_Doc->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		docu.writeEmptyElement("Marker");
+		docu.writeAttribute("label", marker->label);
+		docu.writeAttribute("type", marker->getType());
+		if ((marker->getType() == MARKER2ItemType) && marker->hasItemPtr())
+		{
+			PageItem* item = marker->getItemPtr();
+			assert(item != NULL);
+			docu.writeAttribute("itemName", item->itemName());
+		}
+		else if ((marker->getType() == MARKERVariableTextType) && marker->hasString())
+			docu.writeAttribute("str", marker->getString());
+		else if ((marker->getType() == MARKER2MarkerType) && marker->hasMarker())
+		{
+			QString label = marker->getMarker()->label;
+			MarkerType type = marker->getMarker()->getType();
+			docu.writeAttribute("MARKlabel", label);
+			docu.writeAttribute("MARKtype", type);
+		}
+	}
+	docu.writeEndElement();
+}
 
 void Scribus150Format::writePageSets(ScXmlStreamWriter & docu) 
 {	
@@ -1250,6 +1280,13 @@
 			docu.writeAttribute("Unicode", tmpnum);
 			docu.writeAttribute("COBJ", qHash(item->itemText.object(k)));
 		}
+		else if (ch == SpecialChars::OBJECT && item->itemText.item(k)->marker != NULL)
+		{
+			Marker* mark = item->itemText.item(k)->marker;
+			docu.writeEmptyElement("MARKER");
+			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");
 		else if (ch == SpecialChars::TAB)
Index: scribus/plugins/fileloader/scribus150format/scribus150format.cpp
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format.cpp	(wersja 17181)
+++ scribus/plugins/fileloader/scribus150format/scribus150format.cpp	(kopia robocza)
@@ -369,6 +369,11 @@
 			success = readPattern(m_Doc, reader, fileDir);
 			if (!success) break;
 		}
+		if (tagName == "Markers")
+		{
+			success = readMarkers(m_Doc, reader);
+			if (!success) break;
+		}
 	}
 	if (reader.hasError())
 	{
@@ -829,6 +834,11 @@
 			success = readPattern(m_Doc, reader, fileDir);
 			if (!success) break;
 		}
+		if (tagName == "Markers")
+		{
+			success = readMarkers(m_Doc, reader);
+			if (!success) break;
+		}
 	}
 
 	if (reader.hasError())
@@ -1172,6 +1182,9 @@
 	WeldItems.clear();
 	WeldID.clear();
 	LinkID.clear();
+	markeredItemsList.clear();
+	markeredMarkersList.clear();
+	
 
 	m_Doc->GroupCounter = 1;
 	m_Doc->LastAuto = 0;
@@ -1433,6 +1446,11 @@
 			if (!success)
 				break;
 		}
+		if (tagName == "Markers")
+		{
+			success = readMarkers(m_Doc, reader);
+			if (!success) break;
+		}
 	}
 
 	if (reader.hasError())
@@ -1724,6 +1742,7 @@
 			gItem->groupItemList = gpL;
 		}
 	}
+	updateMarkersPtr();
 	
 	// reestablish first/lastAuto
 	m_Doc->FirstAuto = m_Doc->LastAuto;
@@ -2761,6 +2780,68 @@
 	return !reader.hasError();
 }
 
+bool Scribus150Format::readMarkers(ScribusDoc* doc, ScXmlStreamReader& reader)
+{
+	QStringRef tagName = reader.name();
+	doc->markersMap.clear();
+	markeredItemsList.clear();
+	markeredMarkersList.clear();
+	while(!reader.atEnd() && !reader.hasError())
+	{
+		reader.readNext();
+		if (reader.isEndElement() && reader.name() == tagName)
+			break;
+		if(reader.isStartElement() && reader.name() == "Marker")
+		{
+			ScXmlStreamAttributes attrs = reader.scAttributes();
+			MarkerData d;
+			d.itemName = "";
+			d.itemPtr = NULL;
+			d.mrkPtr = NULL;
+			d.strPtr = NULL;
+
+			QString label = "";
+			if (attrs.hasAttribute("label"))
+				label = attrs.valueAsString("label");
+
+			MarkerType type = MARKERNoType;
+			if (attrs.hasAttribute("type"))
+				type = (MarkerType) attrs.valueAsInt("type");
+
+			if (label != "" && type != MARKERNoType)
+			{
+				Marker* mark = new Marker;
+				mark->label=attrs.valueAsString("label");
+				mark->setType((MarkerType) attrs.valueAsInt("type"));
+				doc->markersMap.insert(mark->label, mark);
+
+				if (type == MARKERVariableTextType && attrs.hasAttribute("str"))
+					mark->setString(attrs.valueAsString("str"));
+				if (type == MARKER2ItemType && attrs.hasAttribute("itemName"))
+				{
+					QString itemName = attrs.valueAsString("itemName");
+					markeredItemsList.insert(itemName, mark);
+				}
+				if (type == MARKER2MarkerType && attrs.hasAttribute("MARKlabel"))
+				{
+					QString mark2Label = attrs.valueAsString("MARKlabel");
+					MarkerType mark2Type = (MarkerType) attrs.valueAsInt("MARKtype");
+					Marker* mark2 = doc->getMarkerDefinied(mark2Label, mark2Type);
+					if (mark2 != NULL) //marker is not defined yet, insert into temp list for update to pointers later
+						mark->setMarker(mark2);
+					else
+					{
+						QMap<QString, MarkerType> mark2map;
+						mark2map.insert(mark2Label, mark2Type);
+						markeredMarkersList.insert(mark, mark2map);
+					}
+				}
+			}
+		}
+	}
+	return !reader.hasError();
+}
+
 bool Scribus150Format::readSections(ScribusDoc* doc, ScXmlStreamReader& reader)
 {
 	QStringRef tagName = reader.name();
@@ -3214,6 +3295,25 @@
 				doc->Items = DItems;
 			}
 		}
+		if (tName == "MARKER")
+		{
+			if (newItem->asTextFrame())
+			{
+				QString l = tAtt.valueAsString("label");
+				MarkerType t = (MarkerType) tAtt.valueAsInt("type");
+				Marker* mark = m_Doc->getMarkerDefinied(l, t);
+				if (mark == NULL)
+					qDebug() << "Undefinied marker label ["<< l << "] type " << t;
+				else
+				{
+					//set pointer to item holds marker in his text
+					if (t == MARKERAnchorType)
+						mark->setItemPtr(newItem);
+					mark->OwnPage = newItem->OwnPage;
+					newItem->itemText.insertMarker(mark, newItem->itemText.length());
+				}
+			}
+		}
 		if (tName == "WeldEntry")
 		{
 			PageItem::weldingInfo wInf;
@@ -4535,6 +4635,9 @@
 	itemNextF.clear();
 	WeldItems.clear();
 	WeldID.clear();
+	markeredItemsList.clear();
+	markeredMarkersList.clear();
+	
 
  	QString f(readSLA(fileName));
 	if (f.isEmpty())
@@ -5265,3 +5368,51 @@
 	*num2 = counter2;
 	return success;
 }
+
+void Scribus150Format::updateMarkersPtr() //after document load items pointers should be updated in markeredItemList
+{
+	if (!markeredItemsList.isEmpty())
+	{
+		QMap<QString,Marker*>::Iterator markIt;
+		for (markIt = markeredItemsList.begin(); markIt != markeredItemsList.end(); ++markIt)
+		{
+			QString itemName = markIt.key();
+			Marker* marker = markIt.value();
+			if (m_Doc->itemNameExists(itemName))
+			{
+				marker->setItemPtr(m_Doc->getItemFromName(itemName));
+				marker->setString(QString("%1").arg(marker->getItemPtr()->OwnPage +1));
+			}
+			else
+			{
+				qWarning() << "wrong marker [" << marker->label << "] data - item name [" << itemName << "] not exists - DELETING MARKER";
+				if (!m_Doc->eraseMarker(marker))
+					qWarning() << "Erase marker [" << marker->label << "] failed - was it definied?";
+			}
+		}
+	}
+	if (!markeredMarkersList.isEmpty())
+	{
+		QMap<Marker*,QMap<QString, MarkerType> >::iterator markIt;
+		for (markIt = markeredMarkersList.begin(); markIt != markeredMarkersList.end(); ++markIt)
+		{
+			Marker* mark = markIt.key();
+			QMap<QString, MarkerType> mark2map = markIt.value();
+			QString label2 = mark2map.begin().key();
+			MarkerType type2 = mark2map.begin().value();
+			Marker* mark2 = m_Doc->getMarkerDefinied(label2, type2);
+			if (mark2 != NULL)
+			{
+				mark->setMarker(mark2);
+				mark->setString(QString("%1").arg(mark2->getItemPtr()->OwnPage +1));
+			}
+			else
+			{
+				qWarning() << "wrong marker [" << mark->label << "] data - pointed merker name [" << label2 << "] not exists - DELETING MARKER";
+				if (!m_Doc->eraseMarker(mark))
+					qWarning() << "Erase marker [" << mark->label << "] failed - was it definied?";
+
+			}
+		}
+	}
+}
Index: scribus/scribus.h
===================================================================
--- scribus/scribus.h	(wersja 17181)
+++ scribus/scribus.h	(kopia robocza)
@@ -74,6 +74,7 @@
 class GuideManager;
 class HelpBrowser;
 class LayerPalette;
+class MarkersManager;
 class Measurements;
 class ScMWMenuManager;
 class ModeToolBar;
@@ -208,6 +209,7 @@
 	GuideManager *guidePalette;
 	CharSelect *charPalette;
 	PropertiesPalette *propertiesPalette;
+	MarkersManager *markersManager;
 	NodePalette *nodePalette;
 	OutlinePalette *outlinePalette;
 	Biblio *scrapbookPalette;
@@ -611,6 +613,20 @@
 	FormatsManager *formatsManager;
 
 	QPointer<HelpBrowser> helpBrowser;
+
+public slots:
+	//insert marker
+	void slotInsertMarker2Marker() { insertMarker(MARKER2MarkerType); }
+	void slotInsertMarkerAnchor() { insertMarker(MARKERAnchorType); }
+	void slotInsertMarkerVariableText() { insertMarker(MARKERVariableTextType); }
+	void slotInsertMarkerItem() { insertMarker(MARKER2ItemType); }
+	void slotInsertMarkerFootnote() { insertMarker(MARKERFootnoteType); }
+	void slotInsertMarkerEndnote() { insertMarker(MARKEREndnoteType); }
+	void slotInsertMarkerIndex() { insertMarker(MARKERIndexType); }
+	void slotEditMarker();
+	void slotUpdateMarkers();
+private:
+	void insertMarker(MarkerType);
 };
 
 #endif
Index: scribus/CMakeLists.txt
===================================================================
--- scribus/CMakeLists.txt	(wersja 17181)
+++ scribus/CMakeLists.txt	(kopia robocza)
@@ -85,6 +85,11 @@
   ui/inserttablerowsdialog.ui
   ui/latexeditor.ui
   ui/newmarginwidgetbase.ui
+ui/marker2item.ui
+ui/marker2marker.ui
+ui/markeranchor.ui
+ui/markervariabletext.ui
+ui/markersmanager.ui
   ui/measurementsbase.ui
   ui/multipleduplicate.ui
   ui/multiprogressdialog.ui
@@ -204,6 +209,7 @@
   latexhelpers.h
   loadsaveplugin.h
   menumanager.h
+markers.h
   navigator.h
   observable.h
   pageitem.h
@@ -310,6 +316,12 @@
   ui/latexeditor.h
   ui/layers.h
   ui/loremipsum.h
+ui/markerinsertdlgbase.h
+ui/marker2item.h
+ui/marker2marker.h
+ui/markeranchor.h
+ui/markervariabletext.h
+ui/markersmanager.h
   ui/margindialog.h
   ui/marginpresetlayout.h
   ui/marginwidget.h
@@ -734,6 +746,11 @@
   ui/linecombo.cpp
   ui/linkbutton.cpp
   ui/loremipsum.cpp
+ui/marker2item.cpp
+ui/marker2marker.cpp
+ui/markeranchor.cpp
+ui/markervariabletext.cpp
+ui/markersmanager.cpp
   ui/margindialog.cpp
   ui/marginpresetlayout.cpp
   ui/marginwidget.cpp
markers3.patch (80,348 bytes)   

Mike

2012-01-05 16:53

reporter   ~0027464

This patch seems very very very nice to me :-)

jghali

2012-01-05 22:20

administrator   ~0027468

ui/marker2item.h and ui/markersmanager.h still missing :S

cezaryece

2012-01-09 11:20

updater   ~0027497

This I check patch applying it on fresh working copy...

cezaryece

2012-01-09 11:20

updater  

markers4.patch (88,046 bytes)   
Index: scribus/scribusdoc.cpp
===================================================================
--- scribus/scribusdoc.cpp	(wersja 17181)
+++ scribus/scribusdoc.cpp	(kopia robocza)
@@ -100,6 +100,12 @@
 #include "colormgmt/sccolormgmtenginefactory.h"
 #include "ui/hruler.h"
 #include "ui/layers.h"
+#include "ui/markerinsertdlgbase.h"
+#include "ui/marker2item.h"
+#include "ui/marker2marker.h"
+#include "ui/markeranchor.h"
+#include "ui/markervariabletext.h"
+#include "ui/markersmanager.h"
 #include "ui/scmessagebox.h"
 #include "ui/storyeditor.h"
 
@@ -635,6 +641,11 @@
 			delete pa.items.takeFirst();
 		}
 	}
+	QList<Marker*> marks = markersMap.values();
+	for (int i =0; i < marks.count(); ++i)
+		delete marks[i];
+	marks.clear();
+	markersMap.clear();
 	docPatterns.clear();
 	docGradients.clear();
 	while (!DocItems.isEmpty())
@@ -14627,6 +14638,327 @@
 	}
 }
 
+Marker* ScribusDoc::getMarkerDefinied(QString l, MarkerType t)
+{
+	if (markersMap.contains(l))
+	{
+		QList<Marker*> mlist = markersMap.values(l);
+		QList<Marker*>::const_iterator i;
+		for (i = mlist.constBegin(); i != mlist.constEnd(); ++i)
+		{
+			if ((*i)->getType() == t)
+				return (*i);
+		}
+	}
+	return NULL;
+}
+
+PageItem* ScribusDoc::findMarker(Marker* marker, int &lastItem)
+{
+	lastItem++;
+	for (int a = lastItem; a < Items->count(); ++a)
+	{
+		PageItem* currItem = Items->at(a);
+		if (currItem->isTextFrame() && currItem->itemText.length() > 0)
+		{
+			for (int i = currItem->firstInFrame(); i < currItem->itemText.length(); i++)
+			{
+				ScText* hl = currItem->itemText.item(i);
+				if ((hl->ch == SpecialChars::OBJECT) && (hl->marker == marker))
+				{
+					lastItem = a;
+					return currItem;
+				}
+			}
+		}
+	}
+	lastItem = 0;
+	return NULL;
+}
+
+PageItem* ScribusDoc::findMarker(Marker* marker)
+{
+	int temp = -1;
+	return findMarker(marker,temp);
+}
+
+PageItem* ScribusDoc::findMarker(QString label, MarkerType type)
+{
+	return findMarker(getMarkerDefinied(label, type));
+}
+
+bool ScribusDoc::findMarkerCPos(Marker* marker, PageItem* &currItem, int &pos)
+{
+	if (currItem->isTextFrame() && currItem->itemText.length() > 0)
+	{
+		for (pos = currItem->firstInFrame(); pos < currItem->itemText.length(); pos++)
+		{
+			ScText* hl = currItem->itemText.item(pos);
+			if ((hl->ch == SpecialChars::OBJECT) && (hl->marker == marker))
+				return true;
+		}
+	}
+	return false;
+}
+
+bool ScribusDoc::eraseMarker(Marker *marker)
+{
+	bool found = false;
+	QMap<QString, Marker*>::Iterator mIt = markersMap.find(marker->label);
+	//find markers pointed to that marker
+	while (mIt != markersMap.end())
+	{
+		Marker* mrk = (Marker*) mIt.value();
+		if ((mrk->getType()==MARKER2MarkerType) && (mrk->getMarker() == marker))
+			mrk->setMarker(NULL);
+		mIt++;
+	}
+	//find and delete all marker`s apperences in text
+	int MPos;
+	PageItem* item = findMarker(marker);
+	int itemIndex;
+	while (item != NULL)
+	{
+		itemIndex = DocItems.indexOf(item);
+		while (findMarkerCPos(marker, item, MPos))
+		{
+			item->itemText.select(MPos,1);
+			item->asTextFrame()->deleteSelectedTextFromFrame();
+		}
+		found = true;
+		item->update();
+		item = findMarker(marker,itemIndex);
+	}
+	mIt = markersMap.find(marker->label);
+	while (mIt != markersMap.end())
+	{
+		Marker* mrk = (Marker*) mIt.value();
+		if (mrk == marker)
+		{
+			markersMap.erase(mIt);
+			break;
+		}
+		mIt++;
+	}
+	return found;
+}
+
+bool ScribusDoc::eraseMarker(QString label, MarkerType type)
+{
+	return eraseMarker(getMarkerDefinied(label, type));
+}
+
+void ScribusDoc::editMarkerDlg(Marker * marker)
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	QVector<Marker*> markerList;
+	for(markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+		Marker* mark = markIt.value();
+		markerList.push_back(mark);
+	}
+	MarkerInsertDlg* editMDialog = NULL;
+	switch (marker->getType())
+	{
+	case MARKERAnchorType:
+		editMDialog = (MarkerInsertDlg*) new MarkerAnchorDlg(scMW());
+		editMDialog->setValues(marker->label);
+		break;
+	case MARKERVariableTextType:
+		editMDialog = (MarkerInsertDlg*) new MarkerVariableTextDlg(markerList, false, scMW());
+		editMDialog->setValues(marker->label, marker->getString());
+		break;
+	case MARKER2ItemType:
+		editMDialog = (MarkerInsertDlg*) new Marker2ItemDlg(scMW());
+		editMDialog->setValues(marker->label, marker->getItemPtr());
+		break;
+	case MARKER2MarkerType:
+		editMDialog = (MarkerInsertDlg*) new Marker2MarkerDlg(markerList, marker, scMW());
+		editMDialog->setValues(marker->label, marker->getMarker());
+		break;
+	case MARKERFootnoteType:
+		break;
+	case MARKEREndnoteType:
+		break;
+	case MARKERIndexType:
+		break;
+	default:
+		break;
+	}
+	editMDialog->setWindowTitle(tr("Edit ") + editMDialog->windowTitle());
+	if (editMDialog->exec())
+	{
+		Marker* Mrk = NULL;
+		MarkerData d;
+		 d.strPtr = NULL;
+		 d.itemPtr = NULL;
+		 d.mrkPtr = NULL;
+		 d.itemName = "";
+		QString label = "", text = "";
+		QString oldStr = marker->getString();
+		switch (marker->getType())
+		{
+		case MARKERAnchorType:
+			//only gets label for new marker
+			editMDialog->values(label);
+			if (label.isEmpty() || getMarkerDefinied(label, MARKERAnchorType) != NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			marker->label = label;
+			break;
+		case MARKERVariableTextType:
+			Mrk = editMDialog->values(label, text);
+			if (label.isEmpty() || text.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (Mrk != NULL)
+				marker = Mrk;
+			marker->label = label;
+			if (text != oldStr)
+			{
+				marker->setString(text);
+				updateMarkerVariableText(marker, true);
+			}
+			break;
+		case MARKER2ItemType:
+			editMDialog->values(label, d.itemPtr);
+			if (label.isEmpty() || d.itemPtr == NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.itemPtr != marker->getItemPtr())
+			{
+				marker->setItemPtr(d.itemPtr);
+				marker->setString(QString("%1").arg(d.itemPtr->OwnPage +1));
+			}
+			marker->label = label;
+			break;
+		case MARKER2MarkerType:
+			//gets pointer to referenced marker
+			editMDialog->values(label, d.mrkPtr);
+			if ((d.mrkPtr == NULL) && label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.mrkPtr == NULL)
+			{
+				marker->setMarker(d.mrkPtr);
+				marker->setString("");
+			}
+			else if (d.mrkPtr != marker->getMarker())
+			{
+				marker->setMarker(d.mrkPtr);
+				marker->setString(QString("%1").arg(d.mrkPtr->OwnPage +1));
+			}
+			marker->label = label;
+		case MARKERFootnoteType:
+			break;
+		case MARKEREndnoteType:
+			break;
+		case MARKERIndexType:
+			break;
+		default:
+			break;
+		}
+		changed();
+	}
+	delete editMDialog;
+}
+
+void ScribusDoc::updateMarkerVariableText(Marker* marker, bool forceUpdate)
+{
+	if (marker->getType() == MARKERVariableTextType)
+	{
+		int itemNo = -1;
+		PageItem* mItem = findMarker(marker, itemNo);
+		while (mItem != NULL)
+		{
+			if (forceUpdate)
+				mItem->layout();
+			else
+			{
+				mItem->invalidateLayout();
+			}
+			mItem = findMarker(marker, itemNo);
+		}
+	}
+}
+
+void ScribusDoc::updateMarkers() //update strings (page number) for markers pointed to anchors and items
+{
+	if (isLoading())
+		return;
+	QMap<QString,Marker*>::Iterator markIt;
+	//for all markers
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		//set marker page number
+		PageItem* mItem = findMarker(marker);
+		if (mItem != NULL)
+			marker->OwnPage = mItem->OwnPage;
+		else
+			marker->OwnPage = -1;
+	}
+	QList<Marker*> toDeleting;
+	//run for update markers to items
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		if (marker->getType() == MARKER2ItemType)
+		{
+			if (marker->getItemPtr() == NULL)  //pointer to item not set
+			{
+				qWarning() << "Wrong marker [" << marker->label << "] to item data - no item pointer and no item name - DELETING IT";
+				toDeleting.append(marker);
+				continue;
+			}
+			int page = marker->getItemPtr()->OwnPage +1;
+			if (marker->getString().toInt() != page)
+			{
+				marker->setString(QString("%1").arg(page));
+				(findMarker(marker))->invalidateLayout();
+			}
+		}
+	}
+	//run for markers to markers
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+
+		Marker* marker = markIt.value();
+		if (marker->getType() == MARKER2MarkerType)
+		{
+			Marker* destMark = marker->getMarker();
+			if (destMark == NULL)
+			{
+				qWarning() << QString("Update markers2markers: marker %1 - destination marker is NULL").arg(marker->label);
+				toDeleting.append(marker);
+				continue;
+			}
+			PageItem* mItem = findMarker(destMark);
+			if (mItem == NULL)
+			{
+				destMark->OwnPage = -1;
+				marker->setString("");
+			}
+			else
+			{
+				destMark->OwnPage = (findMarker(destMark))->OwnPage;
+				int page = destMark->OwnPage +1;
+				if (marker->getString().toInt() != page)
+				{
+					marker->setString(QString("%1").arg(page));
+					(findMarker(marker))->invalidateLayout();
+				}
+			}
+		}
+	}
+	//run for variable text (invalidate frames with variable text)
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+		updateMarkerVariableText(markIt.value(), false);
+	if (!toDeleting.isEmpty())
+	{
+		for (int i = 0; i < toDeleting.count(); i++)
+			eraseMarker(toDeleting.at(i));
+	}
+	scMW()->slotUpdateMarkers();
+	scMW()->markersManager->updateListView();
+}
+
 void ScribusDoc::itemSelection_UnWeld()
 {
 	PageItem *currItem;
Index: scribus/canvasmode_edit.cpp
===================================================================
--- scribus/canvasmode_edit.cpp	(wersja 17181)
+++ scribus/canvasmode_edit.cpp	(kopia robocza)
@@ -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())->marker != NULL))
+			{	//invoke edit marker dialog
+				m_ScMW->slotEditMarker();
+				return;
+			}
 			else
 			{	//Double click in a frame to select a word
 				oldCp = currItem->itemText.cursorPosition();
Index: scribus/sctextstruct.h
===================================================================
--- scribus/sctextstruct.h	(wersja 17181)
+++ scribus/sctextstruct.h	(kopia robocza)
@@ -28,6 +28,7 @@
 #include "styles/paragraphstyle.h"
 
 class PageItem;
+class Marker;
 
 /* Struktur fuer Pageitem Text */
 
@@ -116,7 +117,6 @@
 	InlineFrameData* d;
 };
 
-
 #ifndef NLS_PROTO
 class SCRIBUS_API ScText : public CharStyle
 {
@@ -128,16 +128,17 @@
 	float PRot;
 	float PDx;
 	InlineFrame embedded;
+	Marker* marker;
 	QChar ch;
 	ScText() : 
 		CharStyle(),
 		parstyle(NULL), glyph(), 
-		PtransX(0.0f), PtransY(0.0f), PRot(0.0f), PDx(0.0f), embedded(NULL), ch() {}
+		PtransX(0.0f), PtransY(0.0f), PRot(0.0f), PDx(0.0f), embedded(NULL), marker(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), marker(other.marker), ch(other.ch)
 	{
 		glyph.more = NULL;
 		GlyphLayout *layout = &glyph;
Index: scribus/pageitem.h
===================================================================
--- scribus/pageitem.h	(wersja 17181)
+++ scribus/pageitem.h	(kopia robocza)
@@ -237,15 +237,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();
Index: scribus/pageitem.cpp
===================================================================
--- scribus/pageitem.cpp	(wersja 17181)
+++ scribus/pageitem.cpp	(kopia robocza)
@@ -41,6 +41,7 @@
 #include "cmsettings.h"
 #include "colorblind.h"
 #include "commonstrings.h"
+#include "markers.h"
 
 #include "pageitem_group.h"
 #include "pageitem_textframe.h"
@@ -825,6 +826,20 @@
 	isInlineImage = false;
 }
 
+PageItem::~PageItem()
+{
+	if (tempImageFile != NULL)
+		delete tempImageFile;
+	//delete markers pointed to that item
+	QMap<QString,Marker*>::Iterator markIt;
+	for (markIt = doc()->markersMap.begin(); markIt != doc()->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		if ((marker->getType() == MARKER2ItemType) && (marker->getItemPtr() == this))
+			doc()->eraseMarker(marker);
+	}
+}
+
 void PageItem::setXPos(const double newXPos, bool drawingOnly)
 {
 	Xpos = newXPos;
@@ -2223,6 +2238,15 @@
 		else
 			return "%";
 	}
+	//check for markers
+	else if (ch == SpecialChars::OBJECT)
+	{
+		ScText* hl = itemText.item(base);
+		if (hl->marker != NULL && hl->marker->getType() != MARKERAnchorType && hl->marker->getType() != MARKERIndexType)
+		{
+			chstr = hl->marker->getString();
+		}
+	}
 	return chstr;
 }
 
@@ -2406,6 +2430,12 @@
 			points.addQuadPoint(0, -10, 0, -10, 0, -6, 0, -6);
 			stroke = true;
 		}
+		else if (glyph == SpecialChars::OBJECT.unicode())
+		{
+			points.resize(0);
+			points.addQuadPoint(0, -8, 1, -8, 0, -6, 1, -6);
+			stroke = true;
+		}
 		else // ???
 		{
 			points.resize(0);
Index: scribus/scribusdoc.h
===================================================================
--- scribus/scribusdoc.h	(wersja 17181)
+++ scribus/scribusdoc.h	(kopia robocza)
@@ -40,6 +40,7 @@
 #include "scribusapi.h"
 #include "colormgmt/sccolormgmtengine.h"
 #include "documentinformation.h"
+#include "markers.h"
 #include "observable.h"
 #include "pageitem.h"
 #include "pagestructs.h"
@@ -72,7 +73,7 @@
 class ScPattern;
 class UndoTransaction;
 class Serializer;
-
+class MarkersManager;
 class QProgressBar;
 
 struct SCRIBUS_API NodeEditContext : public MassObservable<QPointF>
@@ -1259,7 +1260,7 @@
 	MassObservable<ScPage*> m_pagesChanged;
 	MassObservable<QRectF> m_regionsChanged;
 	DocUpdater* m_docUpdater;
-	
+
 signals:
 	//Lets make our doc talk to our GUI rather than confusing all our normal stuff
 	/**
@@ -1520,8 +1521,24 @@
 	void updatePict(QString name);
 	void updatePictDir(QString name);
 	void removePict(QString name);
-//welding two items
+// Markers
+public:
+	//list of markers with its lables as keys
+	QMap<QString, Marker*> markersMap;
+	Marker* getMarkerDefinied(QString label, MarkerType type); //returns marker with label and type (labels are unique only for same type markers)
+	PageItem* findMarker(Marker* marker, int &lastItem);
+	PageItem* findMarker(Marker* marker);
+	PageItem* findMarker(QString label, MarkerType type);
+	bool findMarkerCPos(Marker* marker, PageItem* &item, int &CPos);
+	bool eraseMarker(QString label, MarkerType type);
+	bool eraseMarker(Marker* marker);
+	void editMarkerDlg(Marker*);
+	void updateMarkerVariableText(Marker* marker, bool forceUpdate = false); //returns if any text was changed
 public slots:
+	void updateMarkers(); //update strings (page number) for markers pointed to anchors and items
+
+	//welding two items
+public slots:
 	void itemSelection_UnWeld();
 	void itemSelection_Weld();
 	void itemSelection_EditWeld();
Index: scribus/actionmanager.cpp
===================================================================
--- scribus/actionmanager.cpp	(wersja 17181)
+++ scribus/actionmanager.cpp	(kopia robocza)
@@ -240,8 +240,11 @@
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 	name="editJavascripts";
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	name="editMarkers";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 
 	(*scrActions)["editStyles"]->setToggleAction(true);
+	(*scrActions)["editMarkers"]->setToggleAction(true);
 
 	connect( (*scrActions)["editUndoAction"], SIGNAL(triggeredData(int)) , undoManager, SLOT(undo(int)) );
 	connect( (*scrActions)["editRedoAction"], SIGNAL(triggeredData(int)) , undoManager, SLOT(redo(int)) );
@@ -540,10 +543,45 @@
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 	(*scrActions)["stickyTools"]->setToggleAction(true);
 
+	//Markers
+	name="insertMarkerAnchor";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarkerVariableText";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarkerItem";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarker2Marker";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+//	name="insertMarkerFootnote";
+//	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+//	(*scrActions)[name]->setEnabled(true);
+//	name="insertMarkerEndnote";
+//	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+//	(*scrActions)[name]->setEnabled(true);
+//	name="insertMarkerIndex";
+//	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+//	(*scrActions)[name]->setEnabled(true);
+	name="editMarker";
+	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)["insertMarkerAnchor"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerAnchor()) );
+	connect( (*scrActions)["insertMarkerVariableText"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerVariableText()) );
+	connect( (*scrActions)["insertMarkerItem"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerItem()) );
+	connect( (*scrActions)["insertMarker2Marker"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarker2Marker()) );
+//	connect( (*scrActions)["insertMarkerFootnote"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerFootnote()) );
+//	connect( (*scrActions)["insertMarkerEndnote"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerEndnote()) );
+//	connect( (*scrActions)["insertMarkerIndex"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerIndex()) );
+	connect( (*scrActions)["editMarker"], SIGNAL(triggered()), mainWindow, SLOT(slotEditMarker()) );
 }
 
 void ActionManager::initPageMenuActions()
@@ -1391,6 +1429,7 @@
 //	(*scrActions)["editPatterns"]->setTexts( tr("Patterns..."));
 //	(*scrActions)["editGradients"]->setTexts( tr("Gradients..."));
 	(*scrActions)["editStyles"]->setTexts( tr("S&tyles..."));
+	(*scrActions)["editMarkers"]->setTexts( tr("Markers..."));
 	(*scrActions)["editMasterPages"]->setTexts( tr("&Master Pages..."));
 	(*scrActions)["editJavascripts"]->setTexts( tr("&JavaScripts..."));
 
@@ -1485,6 +1524,14 @@
 	(*scrActions)["insertGlyph"]->setTexts( tr("&Glyph..."));
 	(*scrActions)["insertSampleText"]->setTexts( tr("Sample Text"));
 	(*scrActions)["stickyTools"]->setTexts( tr("Sticky Tools"));
+	(*scrActions)["insertMarkerAnchor"]->setTexts( tr("Anchor Marker"));
+	(*scrActions)["insertMarkerVariableText"]->setTexts( tr("Variable Text"));
+	(*scrActions)["insertMarkerItem"]->setTexts( tr("Reference to Item"));
+	(*scrActions)["insertMarker2Marker"]->setTexts( tr("Reference to Anchor Marker"));
+//	(*scrActions)["insertMarkerFootnote"]->setTexts( tr("Footnote"));
+//	(*scrActions)["insertMarkerEndnote"]->setTexts( tr("Endnote"));
+//	(*scrActions)["insertMarkerIndex"]->setTexts( tr("Index entry"));
+	(*scrActions)["editMarker"]->setTexts( tr("Edit Marker"));
 
 	//Page menu
 	(*scrActions)["pageInsert"]->setTexts( tr("&Insert..."));
@@ -1873,6 +1920,7 @@
 		<< "editReplaceColors"
 //		<< "editPatterns"
 		<< "editStyles"
+		<< "editMarkers"
 		<< "editMasterPages"
 		<< "editJavascripts";
 	//Style
@@ -1978,7 +2026,15 @@
 		<< "toolsInsertRenderFrame"
 		<< "stickyTools"
 		<< "insertGlyph"
-		<< "insertSampleText";
+		<< "insertSampleText"
+		<< "insertMarkerAnchor"
+		<< "insertMarkerVariableText"
+		<< "insertMarkerItem"
+		<< "insertMarker2Marker"
+//		<< "insertMarkerFootnote"
+//		<< "insertMarkerEndnote"
+//		<< "insertMarkerIndex"
+		<< "editMarker";
 
 	itmenu->second
 		<< "unicodeSoftHyphen"
Index: scribus/pageitem_textframe.cpp
===================================================================
--- scribus/pageitem_textframe.cpp	(wersja 17188)
+++ scribus/pageitem_textframe.cpp	(kopia robocza)
@@ -34,7 +34,9 @@
 
 #include "canvas.h"
 #include "commonstrings.h"
+#include "fonts/scface.h"
 #include "hyphenator.h"
+#include "markers.h"
 #include "pageitem.h"
 #include "pageitem_group.h"
 #include "pageitem_textframe.h"
@@ -53,6 +55,12 @@
 #include "util.h"
 #include "util_math.h"
 
+#include "ui/markerinsertdlgbase.h"
+#include "ui/marker2item.h"
+#include "ui/marker2marker.h"
+#include "ui/markeranchor.h"
+#include "ui/markervariabletext.h"
+#include "ui/markersmanager.h"
 #include "ui/guidemanager.h"
 
 #include <cairo.h>
@@ -1392,6 +1400,15 @@
 		for (int a = firstInFrame(); a < itemText.length(); ++a)
 		{
 			hl = itemText.item(a);
+			if (hl->ch == SpecialChars::OBJECT && hl->marker != NULL)
+			{
+				hl->glyph.glyph = SpecialChars::OBJECT.unicode() + ScFace::CONTROL_GLYPHS;
+				if (hl->marker->getType() == MARKERAnchorType || hl->marker->getType() == MARKERIndexType)
+				{
+					hl->glyph.shrink();
+					continue;
+				}
+			}
 			if (a > 0 && itemText.text(a-1) == SpecialChars::PARSEP)
 				style = itemText.paragraphStyle(a);
 			if (current.itemsInLine == 0)
@@ -1525,8 +1542,12 @@
 				// 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 = charStyle.font().realCharHeight(chstr[0], 1);
-				double realCharAscent = charStyle.font().realCharAscent(chstr[0], 1);
+				double realCharHeight = 0.0, realCharAscent = 0.0;
+				for (int i = 0; i < chstr.length(); i++)
+				{
+					realCharHeight = qMax(realCharHeight, charStyle.font().realCharHeight(chstr[i], 1));
+					realCharAscent = qMax(realCharAscent, charStyle.font().realCharAscent(chstr[i], 1));
+				}
 				double fontAscent     = charStyle.font().ascent(style.charStyle().fontSize() / 10.0);
 				if (realCharHeight == 0.0)
 					realCharHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
@@ -1591,11 +1612,19 @@
 				}
 				else
 				{
-					double realCharHeight = charStyle.font().realCharHeight(chstr[0], charStyle.fontSize() / 10.0);
+					double realCharHeight = 0.0;
+					wide = 0.0; realAsce = 0.0;
+					//
+					for (int i = 0; i < chstr.length(); i++)
+					{
+						realCharHeight = qMax(realCharHeight, charStyle.font().realCharHeight(chstr[i], charStyle.fontSize() / 10.0));
+						realAsce = qMax(realAsce, charStyle.font().realCharHeight(chstr[i], chsd / 10.0));
+						wide += charStyle.font().realCharWidth(chstr[i], chsd / 10.0);
+					}
+					wide = (wide* scaleH) + (1 - scaleH);
+					realAsce = realAsce  * scaleV + offset;
 					if (realCharHeight == 0)
 						realCharHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
-					wide = (charStyle.font().realCharWidth(chstr[0], chsd / 10.0) * scaleH) + (1 - scaleH); //dropcaps are to close to next glyphs if glyphs are hard scaled
-					realAsce = charStyle.font().realCharHeight(chstr[0], chsd / 10.0) * scaleV + offset;
 					asce = charStyle.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;
@@ -1619,12 +1648,19 @@
 					desc = realDesc = 0;
 				else
 				{
+					for (int i = 0; i < chstr.length(); i++)
+					{
+						if (chstr[i] == SpecialChars::OBJECT)
+							continue;
+						realDesc = qMax(realDesc, charStyle.font().realCharDescent(chstr[i], hlcsize10));
+						realAsce = charStyle.font().realCharAscent(chstr[i], hlcsize10);
+					}
+					realDesc =  realDesc * scaleV - offset;
 					desc = -charStyle.font().descent(hlcsize10);
-					realDesc = charStyle.font().realCharDescent(chstr[0], hlcsize10) * scaleV - offset;
 					current.rememberShrinkStretch(hl->ch, wide, style);
 				}
 				asce = charStyle.font().ascent(hlcsize10);
-				realAsce = charStyle.font().realCharAscent(chstr[0], hlcsize10) * scaleV + offset;
+				realAsce = realAsce * scaleV + offset;
 			}
 
 			//check for Y position at beginning of line
@@ -1935,7 +1971,12 @@
 			
 			// remember y pos
 			if (DropCmode)
-				hl->glyph.yoffset -= charStyle.font().realCharHeight(chstr[0], chsd / 10.0) - charStyle.font().realCharAscent(chstr[0], chsd / 10.0);
+			{
+				double yoffset = 0.0;
+				for (int i = 0; i < chstr.length(); i++)
+					yoffset = qMax(yoffset, charStyle.font().realCharHeight(chstr[i], chsd / 10.0) - charStyle.font().realCharAscent(chstr[i], chsd / 10.0));
+				hl->glyph.yoffset -= yoffset;
+			}
 			
 			// remember x pos
 			double breakPos = current.xPos;
@@ -2771,11 +2812,13 @@
 			{
 				bool selecteds = itemText.selected(as);
 				hls = itemText.item(as);
+				if (hls->marker != NULL && (hls->marker->getType() == MARKERAnchorType || hls->marker->getType() == MARKERIndexType))
+					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()) && (hls->ch == SpecialChars::OBJECT && hls->embedded.hasItem()))
 					    || previousWasObject)
 					{
 						sFList << selectedFrame;
@@ -2792,7 +2835,7 @@
 							asce = charStyleS.font().ascent(charStyleS.fontSize() / 10.0);
 							wide = hls->glyph.wide();
 							QRectF scr;
-							if ((hls->ch == SpecialChars::OBJECT)  && (hls->embedded.hasItem()))
+							if (hls->ch == SpecialChars::OBJECT && hls->embedded.hasItem())
 							{
 								double ww = (hls->embedded.getItem()->gWidth + hls->embedded.getItem()->lineWidth()) * hls->glyph.scaleH;
 								double hh = (hls->embedded.getItem()->gHeight + hls->embedded.getItem()->lineWidth()) * hls->glyph.scaleV;
@@ -4031,3 +4074,231 @@
 {
 	invalidateLayout();
 }
+
+void PageItem_TextFrame::insertMarkerDlg(MarkerType markerType)
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	QVector<Marker*> markerList;
+	for (markIt = m_Doc->markersMap.begin(); markIt != m_Doc->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		markerList.push_back(marker);
+	}
+	MarkerInsertDlg* insertMDialog = NULL;
+	switch (markerType)
+	{
+	case MARKERAnchorType:
+		insertMDialog = (MarkerInsertDlg*) new MarkerAnchorDlg(m_Doc->scMW());
+		break;
+	case MARKERVariableTextType:
+		insertMDialog = (MarkerInsertDlg*) new MarkerVariableTextDlg(markerList, true, m_Doc->scMW());
+		break;
+	case MARKER2ItemType:
+		insertMDialog = (MarkerInsertDlg*) new Marker2ItemDlg(m_Doc->scMW());
+		break;
+	case MARKER2MarkerType:
+		insertMDialog = (MarkerInsertDlg*) new Marker2MarkerDlg(markerList, NULL, m_Doc->scMW());
+		break;
+	case MARKERFootnoteType:
+		break;
+	case MARKEREndnoteType:
+		break;
+	case MARKERIndexType:
+		break;
+	}
+	if (insertMDialog == NULL)
+	{
+		qDebug() << "Dialog not implemented for markers type " << markerType;
+		return;
+	}
+	insertMDialog->setWindowTitle(tr("Insert new ") + insertMDialog->windowTitle());
+	if (insertMDialog->exec())
+	{
+		Marker* Mrk = NULL;
+		MarkerData d;
+		 d.strPtr = NULL;
+		 d.itemPtr = NULL;
+		 d.mrkPtr = NULL;
+		QString label = "", text = "";
+		switch (markerType)
+		{
+		case MARKERAnchorType:
+			//only gets label for new marker
+			insertMDialog->values(label);
+			if (label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.itemPtr = this;
+			break;
+		case MARKERVariableTextType:
+			Mrk = insertMDialog->values(label, text);
+			if ((Mrk == NULL) && (label.isEmpty() || text.isEmpty()))
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.strPtr = new QString(text);
+			break;
+		case MARKER2ItemType:
+			insertMDialog->values(label, d.itemPtr);
+			if (d.itemPtr == NULL || label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.strPtr = new QString(QString::number(d.itemPtr->OwnPage +1));
+			break;
+		case MARKER2MarkerType:
+			//gets pointer to referenced marker
+			insertMDialog->values(label, d.mrkPtr);
+			if (d.mrkPtr == NULL || label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.strPtr = new QString(QString::number(d.mrkPtr->OwnPage +1));
+		case MARKERFootnoteType:
+			break;
+		case MARKEREndnoteType:
+			break;
+		case MARKERIndexType:
+			break;
+		}
+		//check if marker with such label exist already
+		if (markerType != MARKERVariableTextType && m_Doc->getMarkerDefinied(label, markerType) != NULL)
+			return; //FIX ME here user should be warned that inserting of marker fails and why
+
+		if (Mrk == NULL)
+		{
+			Mrk = new Marker;
+			Mrk->setValues(label, OwnPage, markerType, d);
+			m_Doc->markersMap.insert(label,Mrk);
+		}
+		else
+		{ // that must be variable text marker
+			Mrk->setStrPtr(d.strPtr);
+			m_Doc->updateMarkerVariableText(Mrk, true);
+		}
+		itemText.insertMarker(Mrk);
+		Mrk->OwnPage = OwnPage;
+		update();
+		m_Doc->changed();
+	}
+	delete insertMDialog;
+	m_Doc->scMW()->markersManager->updateListView();
+}
+
+void PageItem_TextFrame::editMarkerDlg(Marker * marker)
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	QVector<Marker*> markerList;
+	for(markIt = m_Doc->markersMap.begin(); markIt != m_Doc->markersMap.end(); ++markIt)
+	{
+		Marker* mark = markIt.value();
+		markerList.push_back(mark);
+	}
+	MarkerInsertDlg* editMDialog = NULL;
+	switch (marker->getType())
+	{
+	case MARKERAnchorType:
+		editMDialog = (MarkerInsertDlg*) new MarkerAnchorDlg(m_Doc->scMW());
+		editMDialog->setValues(marker->label);
+		break;
+	case MARKERVariableTextType:
+		editMDialog = (MarkerInsertDlg*) new MarkerVariableTextDlg(markerList, true, m_Doc->scMW());
+		editMDialog->setValues(marker->label, marker->getString());
+		break;
+	case MARKER2ItemType:
+		editMDialog = (MarkerInsertDlg*) new Marker2ItemDlg(m_Doc->scMW());
+		editMDialog->setValues(marker->label, marker->getItemPtr());
+		break;
+	case MARKER2MarkerType:
+		editMDialog = (MarkerInsertDlg*) new Marker2MarkerDlg(markerList, marker, m_Doc->scMW());
+		editMDialog->setValues(marker->label, marker->getMarker());
+		break;
+	case MARKERFootnoteType:
+		break;
+	case MARKEREndnoteType:
+		break;
+	case MARKERIndexType:
+		break;
+	default:
+		break;
+	}
+	editMDialog->setWindowTitle(tr("Edit ") + editMDialog->windowTitle());
+	if (editMDialog->exec())
+	{
+		Marker* Mrk = NULL;
+		MarkerData d;
+		 d.strPtr = NULL;
+		 d.itemPtr = NULL;
+		 d.mrkPtr = NULL;
+		 d.itemName = "";
+		QString label = "", text = "";
+		QString oldStr = marker->getString();
+		switch (marker->getType())
+		{
+		case MARKERAnchorType:
+			//only gets label for new marker
+			editMDialog->values(label);
+			if (label.isEmpty() || m_Doc->getMarkerDefinied(label, MARKERAnchorType) != NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			marker->label = label;
+			break;
+		case MARKERVariableTextType:
+			Mrk = editMDialog->values(label, text);
+			if ((Mrk == NULL) && (label.isEmpty() || text.isEmpty()))
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (Mrk != NULL)
+			{
+				if (Mrk != marker)
+				{
+					ScText* hl = itemText.item(itemText.cursorPosition());
+					hl->marker = Mrk;
+					marker = Mrk;
+				}
+				marker->label = label;
+				if (text != oldStr)
+				{
+					marker->setString(text);
+					if (marker->getString() != oldStr)
+						m_Doc->updateMarkerVariableText(marker, true);
+				}
+			}
+			else
+			{
+				d.strPtr = new QString(text);
+				Mrk = new Marker;
+				Mrk->setValues(label, OwnPage, MARKERVariableTextType, d);
+				m_Doc->markersMap.insert(label,Mrk);
+				ScText* hl = itemText.item(itemText.cursorPosition());
+				hl->marker = Mrk;
+			}
+			break;
+		case MARKER2ItemType:
+			editMDialog->values(label, d.itemPtr);
+			if (label.isEmpty() || d.itemPtr == NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.itemPtr != marker->getItemPtr())
+			{
+				marker->setItemPtr(d.itemPtr);
+				marker->setString(QString("%1").arg(d.itemPtr->OwnPage +1));
+			}
+			marker->label = label;
+			break;
+		case MARKER2MarkerType:
+			//gets pointer to referenced marker
+			editMDialog->values(label, d.mrkPtr);
+			if ((d.mrkPtr == NULL) && label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.mrkPtr != marker->getMarker())
+			{
+				marker->setMarker(d.mrkPtr);
+				marker->setString(QString("%1").arg(d.mrkPtr->OwnPage +1));
+			}
+			marker->label = label;
+		case MARKERFootnoteType:
+			break;
+		case MARKEREndnoteType:
+			break;
+		case MARKERIndexType:
+			break;
+		default:
+			break;
+		}
+		update();
+		m_Doc->changed();
+		m_Doc->scMW()->markersManager->updateListView();
+	}
+	delete editMDialog;
+}
Index: scribus/ui/markersmanager.ui
===================================================================
--- scribus/ui/markersmanager.ui	(wersja 0)
+++ scribus/ui/markersmanager.ui	(wersja 0)
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MarkersManager</class>
+ <widget class="QDialog" name="MarkersManager">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>253</width>
+    <height>249</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>200</width>
+    <height>100</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <property name="modal">
+   <bool>false</bool>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QListWidget" name="listView">
+     <property name="editTriggers">
+      <set>QAbstractItemView::DoubleClicked</set>
+     </property>
+     <property name="showDropIndicator" stdset="0">
+      <bool>false</bool>
+     </property>
+     <property name="selectionMode">
+      <enum>QAbstractItemView::NoSelection</enum>
+     </property>
+     <property name="selectionBehavior">
+      <enum>QAbstractItemView::SelectItems</enum>
+     </property>
+     <property name="horizontalScrollMode">
+      <enum>QAbstractItemView::ScrollPerPixel</enum>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QPushButton" name="UpdateButton">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="text">
+      <string>Update All Markers</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QSplitter" name="splitter">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <widget class="QPushButton" name="EditButton">
+      <property name="text">
+       <string>Edit</string>
+      </property>
+     </widget>
+     <widget class="QPushButton" name="DeleteButton">
+      <property name="text">
+       <string>Delete</string>
+      </property>
+     </widget>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
Index: scribus/ui/marker2marker.ui
===================================================================
--- scribus/ui/marker2marker.ui	(wersja 0)
+++ scribus/ui/marker2marker.ui	(wersja 0)
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Marker2MarkerDlg</class>
+ <widget class="QDialog" name="Marker2MarkerDlg">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>362</width>
+    <height>103</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>0</width>
+    <height>103</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>103</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QSplitter" name="splitter">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <widget class="QLabel" name="label_2">
+      <property name="text">
+       <string>Label:</string>
+      </property>
+     </widget>
+     <widget class="QLineEdit" name="labelEdit"/>
+    </widget>
+   </item>
+   <item>
+    <widget class="QSplitter" name="splitter_2">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <widget class="QLabel" name="label">
+      <property name="text">
+       <string>Select marker:</string>
+      </property>
+     </widget>
+     <widget class="QComboBox" name="LabelList">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="editable">
+       <bool>false</bool>
+      </property>
+      <property name="currentIndex">
+       <number>-1</number>
+      </property>
+      <property name="duplicatesEnabled">
+       <bool>false</bool>
+      </property>
+     </widget>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>166</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="buttonBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>Marker2MarkerDlg</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>262</x>
+     <y>90</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>174</x>
+     <y>54</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>Marker2MarkerDlg</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>262</x>
+     <y>90</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>174</x>
+     <y>54</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
Index: scribus/ui/marker2item.h
===================================================================
--- scribus/ui/marker2item.h	(wersja 0)
+++ scribus/ui/marker2item.h	(wersja 0)
@@ -0,0 +1,20 @@
+#ifndef MARKER2ITEM_H
+#define MARKER2ITEM_H
+
+#include "markerinsertdlgbase.h"
+#include "ui_marker2item.h"
+
+class SCRIBUS_API Marker2ItemDlg : public MarkerInsertDlg, private Ui::Marker2ItemDlg
+{
+    Q_OBJECT
+
+public:
+	explicit Marker2ItemDlg(QWidget *parent = 0);
+	virtual void values(QString &label, PageItem* &ptr);
+	virtual void setValues(const QString label, const PageItem* ptr);
+
+protected:
+	void changeEvent(QEvent *e);
+};
+
+#endif // MARKER2ITEM_H
Index: scribus/ui/markerinsertdlgbase.h
===================================================================
--- scribus/ui/markerinsertdlgbase.h	(wersja 0)
+++ scribus/ui/markerinsertdlgbase.h	(wersja 0)
@@ -0,0 +1,39 @@
+#ifndef MARKERINSERTDLG_H
+#define MARKERINSERTDLG_H
+
+#include <QDialog>
+#include <scribusapi.h>
+
+class NotesSet;
+class Marker;
+class PageItem;
+
+class SCRIBUS_API MarkerInsertDlg : public QDialog
+{
+	Q_OBJECT
+
+public:
+	MarkerInsertDlg(const QVector<Marker*>&, QWidget *parent = 0) : QDialog(parent) {}
+	MarkerInsertDlg(const QList<NotesSet*>&, QWidget *parent = 0) : QDialog(parent) {}
+	MarkerInsertDlg(QWidget *parent = 0) : QDialog(parent) {}
+	~MarkerInsertDlg() {}
+
+	virtual void values(QString &label) {}
+	virtual void values(QString &label, PageItem* &item) {}
+	virtual Marker* values(QString& label, QString& text) { return NULL; }
+	virtual void values(QString& label, Marker* &marker) {}
+	virtual NotesSet* values() { return NULL; }
+
+	virtual void setValues(const QString label) {}
+	virtual void setValues(const QString label, const QString text) {}
+	virtual void setValues(const QString label, const PageItem* ptr) {}
+	virtual void setValues(const QString label, const Marker* ptr) {}
+	virtual void setValues(const NotesSet* defaultSet) {}
+	
+signals:
+
+public slots:
+
+};
+
+#endif // MARKERINSERTDLG_H
Index: scribus/ui/markersmanager.h
===================================================================
--- scribus/ui/markersmanager.h	(wersja 0)
+++ scribus/ui/markersmanager.h	(wersja 0)
@@ -0,0 +1,42 @@
+#ifndef MARKERSMANAGER_H
+#define MARKERSMANAGER_H
+
+#include "ui/scrpalettebase.h"
+#include "ui_markersmanager.h"
+#include "markers.h"
+class QEvent;
+class  ScribusDoc;
+
+class SCRIBUS_API MarkersManager : public ScrPaletteBase, Ui::MarkersManager
+{
+	Q_OBJECT
+
+public:
+	explicit MarkersManager(QWidget *parent = 0, const char *name = "MarkersManager");
+	~MarkersManager();
+	void updateListView();
+private:
+	ScribusDoc         *m_doc;
+	PrefsContext       *m_prefs;
+	Marker* getMarkerFromListView();
+	void addListItem(MarkerType typeMrk, QString typeStr, QVector<Marker*> &markers, int &index);
+
+protected:
+	void changeEvent(QEvent *e);
+	void hideEvent(QHideEvent *e);
+	void closeEvent(QCloseEvent *e);
+	void showEvent(QShowEvent *e);
+
+public slots:
+	void setDoc(ScribusDoc *doc);
+	void languageChange();
+
+private slots:
+	void on_UpdateButton_clicked();
+	void on_EditButton_clicked();
+	void on_DeleteButton_clicked();
+	void on_listView_doubleClicked(const QModelIndex &index);
+	void on_listView_itemSelectionChanged();
+};
+
+#endif // MARKERSMANAGER_H
Index: scribus/ui/markervariabletext.ui
===================================================================
--- scribus/ui/markervariabletext.ui	(wersja 0)
+++ scribus/ui/markervariabletext.ui	(wersja 0)
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MarkerVariableTextDlg</class>
+ <widget class="QDialog" name="MarkerVariableTextDlg">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>394</width>
+    <height>117</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>0</width>
+    <height>117</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>117</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Add new Marker for Variable Text</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QHBoxLayout" name="labelLayout">
+     <item>
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Label:</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Text to insert:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="textEdit"/>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>202</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="buttonBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>MarkerVariableTextDlg</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>MarkerVariableTextDlg</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
Index: scribus/ui/marker2item.ui
===================================================================
--- scribus/ui/marker2item.ui	(wersja 0)
+++ scribus/ui/marker2item.ui	(wersja 0)
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Marker2ItemDlg</class>
+ <widget class="QDialog" name="Marker2ItemDlg">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>349</width>
+    <height>102</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>115</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <layout class="QFormLayout" name="formLayout">
+     <property name="fieldGrowthPolicy">
+      <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+     </property>
+     <item row="0" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Label:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QLineEdit" name="labelEdit"/>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Item:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QComboBox" name="ItemList">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="editable">
+        <bool>false</bool>
+       </property>
+       <property name="currentIndex">
+        <number>-1</number>
+       </property>
+       <property name="duplicatesEnabled">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="1" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>164</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="buttonBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>Marker2ItemDlg</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>262</x>
+     <y>90</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>174</x>
+     <y>54</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>Marker2ItemDlg</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>262</x>
+     <y>90</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>174</x>
+     <y>54</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
Index: scribus/ui/markeranchor.ui
===================================================================
--- scribus/ui/markeranchor.ui	(wersja 0)
+++ scribus/ui/markeranchor.ui	(wersja 0)
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MarkerAnchorDlg</class>
+ <widget class="QDialog" name="MarkerAnchorDlg">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>81</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>0</width>
+    <height>81</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>81</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Label:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1">
+    <widget class="QLineEdit" name="labelEdit"/>
+   </item>
+   <item row="1" column="1">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>MarkerAnchorDlg</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>MarkerAnchorDlg</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
Index: scribus/ui/contextmenu.cpp
===================================================================
--- scribus/ui/contextmenu.cpp	(wersja 17181)
+++ scribus/ui/contextmenu.cpp	(kopia robocza)
@@ -94,6 +94,7 @@
 	QMenu *menuLayer = new QMenu(this);
 	QMenu *menuLevel = new QMenu(this);
 	QMenu *menuPDF = new QMenu(this);
+	QMenu *menuMarker = new QMenu(this);
 	QMenu *menuResolution = new QMenu(this);
 //	QMenu *menuWeld = new QMenu(this);
 	
@@ -172,6 +173,25 @@
 			addAction(m_AP->scrActions["fileImportAppendText"]);
 			addAction(m_AP->scrActions["toolsEditWithStoryEditor"]);
 			addAction(m_AP->scrActions["insertSampleText"]);
+			if (m_doc->appMode == modeEdit)
+			{
+				QAction *act2 = addMenu(menuMarker);
+				act2->setText( ScribusView::tr("Insert Marker"));
+				menuMarker->addAction(m_AP->scrActions["insertMarkerAnchor"]);
+				menuMarker->addAction(m_AP->scrActions["insertMarkerVariableText"]);
+				menuMarker->addAction(m_AP->scrActions["insertMarkerItem"]);
+				menuMarker->addAction(m_AP->scrActions["insertMarker2Marker"]);
+//				menuMarker->addAction(m_AP->scrActions["insertMarkerFootnote"]);
+//				menuMarker->addAction(m_AP->scrActions["insertMarkerEndnote"]);
+//				menuMarker->addAction(m_AP->scrActions["insertMarkerIndex"]);
+				if (currItem->itemText.cursorPosition() < currItem->itemText.length())
+				{
+					ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+					if (hl->ch == SpecialChars::OBJECT && hl->marker != NULL)
+						addAction(m_AP->scrActions["editMarker"]);
+				}
+
+			}
 		}
 		else //enable this for, eg, text on a path
 			if (m_actionList.contains("toolsEditWithStoryEditor"))
Index: scribus/text/storytext.cpp
===================================================================
--- scribus/text/storytext.cpp	(wersja 17181)
+++ scribus/text/storytext.cpp	(kopia robocza)
@@ -329,10 +329,13 @@
 		if ((it->ch == SpecialChars::PARSEP)) {
 			removeParSep(i);
 		}
+		Marker* mrk = it->marker;
 //		qDebug("remove char %d at %d", (int) it->ch.unicode(), i);
 		d->takeAt(i);
 		d->len--;
 		delete it;
+		if ((mrk != NULL) && mrk->isUnique())
+			doc->eraseMarker(mrk);
 		// #9592 : adjust selFirst and selLast, those values have to be
 		// consistent in functions such as select()
 		if (i <= selLast) --selLast;
@@ -477,6 +480,15 @@
 	invalidate(pos, pos + 1);
 }
 
+void StoryText::insertMarker(Marker* M, int pos)
+{
+	if (pos < 0)
+		pos = d->cursorPosition;
+
+	insertChars(pos, SpecialChars::OBJECT);
+	const_cast<StoryText *>(this)->d->at(pos)->marker = M;
+}
+
 void StoryText::hyphenateWord(int pos, uint len, char* hyphens)
 {
 	assert(pos >= 0);
Index: scribus/text/storytext.h
===================================================================
--- scribus/text/storytext.h	(wersja 17181)
+++ scribus/text/storytext.h	(kopia robocza)
@@ -126,6 +126,8 @@
 	// Insert object at specific position
  	void insertObject(int pos, PageItem* obj);
  	void replaceChar(int pos, QChar ch);
+	// Insert marker at cursor or specific position
+	void insertMarker(Marker* M, int pos = -1);
 
 	void hyphenateWord(int pos, uint len, char* hyphens);
 	
Index: scribus/markers.h
===================================================================
--- scribus/markers.h	(wersja 0)
+++ scribus/markers.h	(wersja 0)
@@ -0,0 +1,77 @@
+#ifndef MARKERS_H
+#define MARKERS_H
+
+#include <QString>
+#include "scribusapi.h"
+class Marker;
+class PageItem;
+
+enum MarkerType
+{
+	MARKERNoType = -1, //undefinied marker type (wrong situation!)
+	MARKERAnchorType = 0, //empty anchor marker, useful for creating references to it
+	MARKER2ItemType = 1, //reference to page item ID
+	MARKER2MarkerType = 2, //reference other marker
+	MARKERVariableTextType = 3,//marker contain dynamic text
+	MARKERFootnoteType = 4,  //marker contain footnote
+	MARKEREndnoteType = 5,  //marker contain endnote
+	MARKERIndexType = 6 // index entry
+};
+
+struct MarkerData
+{
+	PageItem* itemPtr;
+	QString* strPtr;
+	Marker* mrkPtr;
+	QString itemName;
+};
+
+class SCRIBUS_API Marker
+{
+public:
+	QString label;
+	int OwnPage;
+	Marker() { label = "", OwnPage = -1, typ = MARKERNoType, data.itemPtr = NULL; data.strPtr = NULL; data.mrkPtr = NULL; }
+	Marker(const Marker& other) : label(other.label), OwnPage(other.OwnPage), typ(other.typ), data(other.data) {}
+	~Marker()
+	{
+		if (data.strPtr != NULL)
+			delete data.strPtr;
+	}
+	void setValues(QString l, int p, MarkerType t, MarkerData d) { label = l; OwnPage = p; typ = t; data = d; }
+	MarkerType getType() { return typ; }
+	void setType(MarkerType t) { typ = t; }
+	MarkerData getData() { return data; }
+	void setData(MarkerData d) { data = d; }
+	PageItem* getItemPtr() { return data.itemPtr; }
+	void setItemPtr( PageItem* ptr ) { data.itemPtr = ptr; }
+	QString getItemName() { return data.itemName; }
+	void setItemName( QString name ) { data.itemName = name; }
+	QString* getStrPtr() { return data.strPtr; }
+	QString getString()
+	{
+		if (data.strPtr != NULL)
+			return *data.strPtr;
+		else
+			return "";
+	}
+	void setMarker(Marker* mP) { data.mrkPtr = mP; }
+	Marker* getMarker() { return data.mrkPtr; }
+	void setStrPtr( QString* p ) { data.strPtr = p; }
+	void setString( QString str )
+	{
+		if (data.strPtr != NULL)
+			delete data.strPtr;
+		data.strPtr = new QString(str);
+	}
+
+	bool hasItemPtr() { return data.itemPtr != NULL; }
+	bool hasString() { return getString() != ""; }
+	bool hasMarker() { return data.mrkPtr != NULL; }
+	bool isUnique() { return (typ==MARKERAnchorType || typ==MARKERFootnoteType || typ==MARKEREndnoteType); }
+private:
+	MarkerType typ;
+	MarkerData data;
+};
+
+#endif // MARKERS_H
Index: scribus/scribus.cpp
===================================================================
--- scribus/scribus.cpp	(wersja 17181)
+++ scribus/scribus.cpp	(kopia robocza)
@@ -99,6 +99,7 @@
 #include "gtgettext.h"
 #include "hyphenator.h"
 #include "langmgr.h"
+#include "markers.h"
 #include "pageitem_group.h"
 #include "pageitem_imageframe.h"
 #include "pageitem_latexframe.h"
@@ -163,6 +164,8 @@
 #include "ui/loremipsum.h"
 #include "ui/marginwidget.h"
 #include "ui/margindialog.h"
+#include "ui/markerinsertdlgbase.h"
+#include "ui/markersmanager.h"
 #include "ui/masterpagepalette.h"
 #include "ui/mergedoc.h"
 #include "ui/movepage.h"
@@ -582,6 +585,12 @@
 	connect( styleManager, SIGNAL(paletteShown(bool)), scrActions["editStyles"], SLOT(setChecked(bool)));
 	styleManager->installEventFilter(this);
 
+	// initializing marker`s manager
+	markersManager = new MarkersManager(this, "markersManager");
+	connect( scrActions["editMarkers"], SIGNAL(toggled(bool)), markersManager, SLOT(setPaletteShown(bool)) );
+	connect( markersManager, SIGNAL(paletteShown(bool)), scrActions["editMarkers"], SLOT(setChecked(bool)));
+	markersManager->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)));
@@ -721,6 +730,7 @@
 //	scrMenuMgr->addMenuItem(scrActions["editGradients"], "Edit", false);
 //	scrMenuMgr->addMenuItem(scrActions["editPatterns"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editStyles"], "Edit", false);
+	scrMenuMgr->addMenuItem(scrActions["editMarkers"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editMasterPages"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editJavascripts"], "Edit", false);
 	scrMenuMgr->setMenuEnabled("EditPasteRecent", false);
@@ -837,6 +847,8 @@
 	scrMenuMgr->addMenuItem(scrActions["itemWeld"], "Item", false);
 	scrMenuMgr->addMenuItem(scrActions["itemEditWeld"], "Item", false);
 
+	scrMenuMgr->addMenuItem(scrActions["editMarker"], "Item", false);
+
 	//Insert menu
 	scrMenuMgr->createMenu("Insert", ActionManager::defaultMenuNameEntryTranslated("Insert"));
 	scrMenuMgr->addMenuItem(scrActions["insertFrame"], "Insert", false);
@@ -927,6 +939,15 @@
 
 	scrMenuMgr->addMenuSeparator("Insert");
 	scrMenuMgr->addMenuItem(scrActions["insertSampleText"], "Insert", false);
+	scrMenuMgr->addMenuSeparator("Insert");
+	scrMenuMgr->createMenu("InsertMarker", tr("Markers"), "Insert");
+	scrMenuMgr->addMenuItem(scrActions["insertMarkerAnchor"], "InsertMarker", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarkerVariableText"], "InsertMarker", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarkerItem"], "InsertMarker", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarker2Marker"], "InsertMarker", false);
+//	scrMenuMgr->addMenuItem(scrActions["insertMarkerFootnote"], "InsertMarker", false);
+//	scrMenuMgr->addMenuItem(scrActions["insertMarkerEndnote"], "InsertMarker", false);
+//	scrMenuMgr->addMenuItem(scrActions["insertMarkerIndex"], "InsertMarker", false);
 
 	//Page menu
 	scrMenuMgr->createMenu("Page", ActionManager::defaultMenuNameEntryTranslated("Page"));
@@ -1129,6 +1150,7 @@
 //AV to be replaced with Selection::update and listener in PropertiesPalette
 void ScribusMainWindow::setTBvals(PageItem *currItem)
 {
+	scrActions["editMarker"]->setEnabled(false);
 	if (currItem->itemText.length() != 0)
 	{
 //		int ChPos = qMin(currItem->CPos, static_cast<int>(currItem->itemText.length()-1));
@@ -1142,6 +1164,11 @@
 		emit TextStyle(doc->currentStyle);
 		// to go: (av)
 		propertiesPalette->textPal->updateStyle(doc->currentStyle);
+		if (doc->appMode == modeEdit && currItem->itemText.cursorPosition() < currItem->itemText.length())
+		{
+			ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+			scrActions["editMarker"]->setEnabled((hl->ch == SpecialChars::OBJECT && hl->marker != NULL));
+		}
 	}
 }
 
@@ -1984,6 +2011,7 @@
 		tempView->cmsToolbarButton->setChecked(tempDoc->HasCMS);
 		undoManager->switchStack(tempDoc->DocName);
 		styleManager->setDoc(tempDoc);
+		markersManager->setDoc(tempDoc);
 		tocGenerator->setDoc(tempDoc);
 	}
 	undoManager->setUndoEnabled(true);
@@ -2227,6 +2255,7 @@
 	docCheckerPalette->setDoc(doc);
 	tocGenerator->setDoc(doc);
 	styleManager->setDoc(doc);
+	markersManager->setDoc(doc);
 	symbolPalette->setDoc(doc);
 	modeToolBar->Angle->setValue(doc->itemToolPrefs().calligrapicPenAngle);
 	modeToolBar->PWidth->setValue(doc->itemToolPrefs().calligrapicPenWidth);
@@ -2258,6 +2287,7 @@
 	updateActiveWindowCaption(doc->DocName);
 // 	scrActions["shade100"]->setChecked(true);
 	propertiesPalette->setDoc(doc);
+	markersManager->setDoc(doc);
 	//propertiesPalette->Cpal->displayGradient(0);
 	pagePalette->setView(view);
 	layerPalette->setDoc(doc);
@@ -2397,6 +2427,7 @@
 //	scrActions["editPatterns"]->setEnabled(true);
 //	scrActions["editGradients"]->setEnabled(true);
  	scrActions["editStyles"]->setEnabled(true);
+	scrActions["editMarkers"]->setEnabled(true);
 	scrActions["editMasterPages"]->setEnabled(true);
 	scrActions["editJavascripts"]->setEnabled(true);
 
@@ -2463,6 +2494,7 @@
 	updateActiveWindowCaption(doc->DocName);
 // 	scrActions["shade100"]->setChecked(true);
 	propertiesPalette->setDoc(doc);
+	markersManager->setDoc(doc);
 	symbolPalette->setDoc(doc);
 //	propertiesPalette->Cpal->displayGradient(0);
 //	propertiesPalette->updateColorList();
@@ -2816,6 +2848,16 @@
 		scrActions["toolsCopyProperties"]->setEnabled(true);
 		scrActions["toolsEditWithStoryEditor"]->setEnabled(true);
 		scrActions["insertSampleText"]->setEnabled(true);
+		scrMenuMgr->setMenuEnabled("InsertMarker",true);
+		scrActions["insertMarkerAnchor"]->setEnabled(true);
+		scrActions["insertMarkerVariableText"]->setEnabled(true);
+		scrActions["insertMarkerItem"]->setEnabled(true);
+		scrActions["insertMarker2Marker"]->setEnabled(true);
+//		scrActions["insertMarkerFootnote"]->setEnabled(true);
+//		scrActions["insertMarkerEndnote"]->setEnabled(true);
+//		scrActions["insertMarkerIndex"]->setEnabled(true);
+		scrActions["editMarker"]->setEnabled(false);
+
 		if ((currItem->nextInChain() != 0) || (currItem->prevInChain() != 0))
 		{
 			scrActions["itemConvertToBezierCurve"]->setEnabled(false);
@@ -2844,6 +2886,8 @@
 			setTBvals(currItem);
 			scrActions["editSelectAll"]->setEnabled(true);
 			scrActions["editSelectAllOnLayer"]->setEnabled(false);
+			scrActions["insertSampleText"]->setEnabled(true);
+			scrMenuMgr->setMenuEnabled("InsertMarker",true);
 			charPalette->setEnabled(true, currItem);
 			if (currItem->asTextFrame())
 				enableTextActions(&scrActions, true, currItem->currentStyle().charStyle().font().scName());
@@ -2852,6 +2896,7 @@
 		}
 		else
 		{
+			scrMenuMgr->setMenuEnabled("InsertMarker",false);
 			doc->currentStyle = currItem->itemText.defaultStyle();
 			propertiesPalette->textPal->displayParStyle(doc->currentStyle.parent());
 			propertiesPalette->textPal->displayCharStyle(doc->currentStyle.charStyle().parent());
@@ -3204,6 +3249,7 @@
 //		scanDocument();
 //		docCheckerPalette->buildErrorList(doc);
 //	}
+//	doc->updateMarkers();
 	if (!doc->isModified())
 		doc->setModified(true);
 	updateActiveWindowCaption(doc->DocName + "*");
@@ -4185,6 +4231,7 @@
 			view->DrawNew();
 			slotDocCh();
 			styleManager->setDoc(doc);
+			markersManager->setDoc(doc);
 		}
 	}
 }
@@ -4585,6 +4632,7 @@
 //		scrActions["editPatterns"]->setEnabled(false);
 //		scrActions["editGradients"]->setEnabled(false);
 		scrActions["editStyles"]->setEnabled(false);
+		scrActions["editMarkers"]->setEnabled(false);
 		scrActions["editSearchReplace"]->setEnabled(false);
 		scrActions["editMasterPages"]->setEnabled(false);
 		scrActions["editJavascripts"]->setEnabled(false);
@@ -4690,6 +4738,7 @@
 	charPalette->setDoc(0);
 	tocGenerator->setDoc(0);
 	styleManager->setDoc(0);
+	markersManager->setDoc(0);
 	layerPalette->ClearInhalt();
 	docCheckerPalette->buildErrorList(0);
 	HaveDoc--;
@@ -5073,6 +5122,7 @@
 				styleManager->setDoc(doc);
 				propertiesPalette->unsetDoc();
 				propertiesPalette->setDoc(doc);
+				markersManager->setDoc(doc);
 				symbolPalette->unsetDoc();
 				symbolPalette->setDoc(doc);
 
@@ -5154,6 +5204,7 @@
 				styleManager->setDoc(doc);
 				propertiesPalette->unsetDoc();
 				propertiesPalette->setDoc(doc);
+				markersManager->setDoc(doc);
 				symbolPalette->unsetDoc();
 				symbolPalette->setDoc(doc);
 
@@ -6429,8 +6480,8 @@
 //					view->requestMode(modeEditClip);
 //					return;
 //				}
+				currItem->itemText.setCursorPosition(0);
 				setTBvals(currItem);
-				currItem->itemText.setCursorPosition(0);
 			}
 			scrActions["editPaste"]->setEnabled(false);
 			charPalette->setEnabled(true, currItem);
@@ -7771,6 +7822,7 @@
 	guidePalette->startup();
 	charPalette->startup();
 	styleManager->startup();
+	markersManager->startup();
 	symbolPalette->startup();
 
 	// init the toolbars
@@ -10050,6 +10102,7 @@
 	scrMenuMgr->setMenuEnabled("InsertQuote", enabled);
 	scrMenuMgr->setMenuEnabled("InsertSpace", enabled);
 	scrMenuMgr->setMenuEnabled("InsertLigature", enabled);
+	scrMenuMgr->setMenuEnabled("InsertMarker", enabled);
 }
 
 void ScribusMainWindow::updateTableMenuActions()
@@ -10081,4 +10134,76 @@
 	scrActions["tableAdjustFrameToTable"]->setEnabled(table);
 	scrActions["tableAdjustTableToFrame"]->setEnabled(table);
 }
+void ScribusMainWindow::insertMarker(MarkerType mType)
+{
+	if (HaveDoc && doc->m_Selection->itemAt(0)->isTextFrame() && doc->appMode == modeEdit)
+	{
+		doc->m_Selection->itemAt(0)->asTextFrame()->insertMarkerDlg(mType);
+		update();
+	}
+}
 
+void ScribusMainWindow::slotEditMarker()
+{
+	if (HaveDoc && doc->m_Selection->itemAt(0)->isTextFrame() && doc->appMode == modeEdit)
+	{
+		PageItem * currItem = doc->m_Selection->itemAt(0);
+		if (currItem->itemText.cursorPosition() < currItem->itemText.length())
+		{
+			ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+			if (hl->ch == SpecialChars::OBJECT && hl->marker != NULL)
+			{
+				currItem->asTextFrame()->editMarkerDlg(hl->marker);
+				slotUpdateMarkers();
+			}
+		}
+	}
+}
+
+void ScribusMainWindow::slotUpdateMarkers()
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	for(markIt = doc->markersMap.begin(); markIt != doc->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		int itemIndex = -1;
+		PageItem* item = doc->findMarker(marker, itemIndex);
+		while (item != NULL)
+		{
+			QString iName = item->getUName();
+			int cpos = -1;
+			if (doc->findMarkerCPos(marker, item, cpos))
+			{
+				ScText *hl = item->itemText.item(cpos);
+				if (hl->ch != SpecialChars::OBJECT || hl->marker == NULL)
+					continue;
+				if (hl->marker->getType() == marker->getType() && hl->marker->label == marker->label)
+				{
+					if (marker->getType() != MARKERVariableTextType)
+					{
+						marker->OwnPage = item->OwnPage;
+						if (marker->getType() == MARKER2ItemType)
+						{
+							PageItem* it = marker->getItemPtr();
+							if (it != NULL)
+								marker->setString(QString("%1").arg(it->OwnPage +1));
+							else
+								marker->setString("");
+						}
+						else if (marker->getType() == MARKER2MarkerType)
+						{
+							Marker* m = marker->getMarker();
+							if (m != NULL)
+								marker->setString(QString("%1").arg(m->OwnPage +1));
+							else
+								marker->setString("");
+						}
+					}
+					item->update();
+				}
+			}
+			item = doc->findMarker(marker,itemIndex);
+		}
+	}
+	doc->regionsChanged()->update(QRectF());
+}
Index: scribus/pageitem_textframe.h
===================================================================
--- scribus/pageitem_textframe.h	(wersja 17181)
+++ scribus/pageitem_textframe.h	(kopia robocza)
@@ -29,6 +29,7 @@
 
 #include "scribusapi.h"
 #include "pageitem.h"
+#include "markers.h"
 
 class ScPainter;
 class ScribusDoc;
@@ -117,6 +118,9 @@
 	
 private slots:
 	void slotInvalidateLayout();
+public:
+	void insertMarkerDlg(MarkerType mT = MARKERAnchorType);
+	void editMarkerDlg(Marker * marker);
 };
 
 #endif
Index: scribus/plugins/scriptplugin/scriptercore.cpp
===================================================================
--- scribus/plugins/scriptplugin/scriptercore.cpp	(wersja 17181)
+++ scribus/plugins/scriptplugin/scriptercore.cpp	(kopia robocza)
@@ -18,6 +18,7 @@
 
 #include "runscriptdialog.h"
 #include "ui/helpbrowser.h"
+#include "ui/markersmanager.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
@@ -151,6 +152,7 @@
 	if (ScMW->HaveDoc)
 	{
 		ScMW->propertiesPalette->setDoc(ScMW->doc);
+		ScMW->markersManager->setDoc(ScMW->doc);
 		ScMW->layerPalette->setDoc(ScMW->doc);
 		ScMW->outlinePalette->setDoc(ScMW->doc);
 		ScMW->outlinePalette->BuildTree();
Index: scribus/plugins/fileloader/scribus150format/scribus150format.h
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format.h	(wersja 17181)
+++ scribus/plugins/fileloader/scribus150format/scribus150format.h	(kopia robocza)
@@ -122,7 +122,13 @@
 		bool readPrinterOptions(ScribusDoc* doc, ScXmlStreamReader& reader);
 		bool readSections(ScribusDoc* doc, ScXmlStreamReader& reader);
 		bool readTableOfContents(ScribusDoc* doc, ScXmlStreamReader& reader);
+		bool readMarkers(ScribusDoc* doc, ScXmlStreamReader& reader);
 
+		//lists of items and markers with names only, which need update to pointers
+		QMap<QString, Marker*> markeredItemsList;
+		QMap<Marker*, QMap<QString, MarkerType> > markeredMarkersList;
+		void updateMarkersPtr(); //after document load items pointers should be updated in markeredItemList
+
 		PageItem* pasteItem(ScribusDoc *doc, ScXmlStreamAttributes& attrs, const QString& baseDir, int pagenr = -2 /* currentPage*/);
 
 		void writeCheckerProfiles(ScXmlStreamWriter& docu);
@@ -148,6 +154,7 @@
 		void writePdfOptions(ScXmlStreamWriter& docu);
 		void writeDocItemAttributes(ScXmlStreamWriter& docu);
 		void writeTOC(ScXmlStreamWriter& docu);
+		void writeMarkers(ScXmlStreamWriter & docu);
 		void writePageSets(ScXmlStreamWriter& docu);
 		void writeSections(ScXmlStreamWriter& docu);
 		void writePatterns(ScXmlStreamWriter& docu, const QString& baseDir, bool part = false, Selection* selection = 0);
Index: scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp	(wersja 17181)
+++ scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp	(kopia robocza)
@@ -389,6 +389,7 @@
 	writePdfOptions(docu);
 	writeDocItemAttributes(docu);
 	writeTOC(docu);
+	writeMarkers(docu);
 	writePageSets(docu);
 	writeSections(docu);
 	writePatterns(docu, fileDir);
@@ -1053,6 +1054,35 @@
 	docu.writeEndElement();
 }
 
+void Scribus150Format::writeMarkers(ScXmlStreamWriter & docu)
+{
+	//write list of definied markers to SLA
+	docu.writeStartElement("Markers");
+	QMap<QString,Marker*>::Iterator markIt;
+	for(markIt = m_Doc->markersMap.begin(); markIt != m_Doc->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		docu.writeEmptyElement("Marker");
+		docu.writeAttribute("label", marker->label);
+		docu.writeAttribute("type", marker->getType());
+		if ((marker->getType() == MARKER2ItemType) && marker->hasItemPtr())
+		{
+			PageItem* item = marker->getItemPtr();
+			assert(item != NULL);
+			docu.writeAttribute("itemName", item->itemName());
+		}
+		else if ((marker->getType() == MARKERVariableTextType) && marker->hasString())
+			docu.writeAttribute("str", marker->getString());
+		else if ((marker->getType() == MARKER2MarkerType) && marker->hasMarker())
+		{
+			QString label = marker->getMarker()->label;
+			MarkerType type = marker->getMarker()->getType();
+			docu.writeAttribute("MARKlabel", label);
+			docu.writeAttribute("MARKtype", type);
+		}
+	}
+	docu.writeEndElement();
+}
 
 void Scribus150Format::writePageSets(ScXmlStreamWriter & docu) 
 {	
@@ -1250,6 +1280,13 @@
 			docu.writeAttribute("Unicode", tmpnum);
 			docu.writeAttribute("COBJ", qHash(item->itemText.object(k)));
 		}
+		else if (ch == SpecialChars::OBJECT && item->itemText.item(k)->marker != NULL)
+		{
+			Marker* mark = item->itemText.item(k)->marker;
+			docu.writeEmptyElement("MARKER");
+			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");
 		else if (ch == SpecialChars::TAB)
Index: scribus/plugins/fileloader/scribus150format/scribus150format.cpp
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format.cpp	(wersja 17181)
+++ scribus/plugins/fileloader/scribus150format/scribus150format.cpp	(kopia robocza)
@@ -369,6 +369,11 @@
 			success = readPattern(m_Doc, reader, fileDir);
 			if (!success) break;
 		}
+		if (tagName == "Markers")
+		{
+			success = readMarkers(m_Doc, reader);
+			if (!success) break;
+		}
 	}
 	if (reader.hasError())
 	{
@@ -829,6 +834,11 @@
 			success = readPattern(m_Doc, reader, fileDir);
 			if (!success) break;
 		}
+		if (tagName == "Markers")
+		{
+			success = readMarkers(m_Doc, reader);
+			if (!success) break;
+		}
 	}
 
 	if (reader.hasError())
@@ -1172,6 +1182,9 @@
 	WeldItems.clear();
 	WeldID.clear();
 	LinkID.clear();
+	markeredItemsList.clear();
+	markeredMarkersList.clear();
+	
 
 	m_Doc->GroupCounter = 1;
 	m_Doc->LastAuto = 0;
@@ -1433,6 +1446,11 @@
 			if (!success)
 				break;
 		}
+		if (tagName == "Markers")
+		{
+			success = readMarkers(m_Doc, reader);
+			if (!success) break;
+		}
 	}
 
 	if (reader.hasError())
@@ -1724,6 +1742,7 @@
 			gItem->groupItemList = gpL;
 		}
 	}
+	updateMarkersPtr();
 	
 	// reestablish first/lastAuto
 	m_Doc->FirstAuto = m_Doc->LastAuto;
@@ -2761,6 +2780,68 @@
 	return !reader.hasError();
 }
 
+bool Scribus150Format::readMarkers(ScribusDoc* doc, ScXmlStreamReader& reader)
+{
+	QStringRef tagName = reader.name();
+	doc->markersMap.clear();
+	markeredItemsList.clear();
+	markeredMarkersList.clear();
+	while(!reader.atEnd() && !reader.hasError())
+	{
+		reader.readNext();
+		if (reader.isEndElement() && reader.name() == tagName)
+			break;
+		if(reader.isStartElement() && reader.name() == "Marker")
+		{
+			ScXmlStreamAttributes attrs = reader.scAttributes();
+			MarkerData d;
+			d.itemName = "";
+			d.itemPtr = NULL;
+			d.mrkPtr = NULL;
+			d.strPtr = NULL;
+
+			QString label = "";
+			if (attrs.hasAttribute("label"))
+				label = attrs.valueAsString("label");
+
+			MarkerType type = MARKERNoType;
+			if (attrs.hasAttribute("type"))
+				type = (MarkerType) attrs.valueAsInt("type");
+
+			if (label != "" && type != MARKERNoType)
+			{
+				Marker* mark = new Marker;
+				mark->label=attrs.valueAsString("label");
+				mark->setType((MarkerType) attrs.valueAsInt("type"));
+				doc->markersMap.insert(mark->label, mark);
+
+				if (type == MARKERVariableTextType && attrs.hasAttribute("str"))
+					mark->setString(attrs.valueAsString("str"));
+				if (type == MARKER2ItemType && attrs.hasAttribute("itemName"))
+				{
+					QString itemName = attrs.valueAsString("itemName");
+					markeredItemsList.insert(itemName, mark);
+				}
+				if (type == MARKER2MarkerType && attrs.hasAttribute("MARKlabel"))
+				{
+					QString mark2Label = attrs.valueAsString("MARKlabel");
+					MarkerType mark2Type = (MarkerType) attrs.valueAsInt("MARKtype");
+					Marker* mark2 = doc->getMarkerDefinied(mark2Label, mark2Type);
+					if (mark2 != NULL) //marker is not defined yet, insert into temp list for update to pointers later
+						mark->setMarker(mark2);
+					else
+					{
+						QMap<QString, MarkerType> mark2map;
+						mark2map.insert(mark2Label, mark2Type);
+						markeredMarkersList.insert(mark, mark2map);
+					}
+				}
+			}
+		}
+	}
+	return !reader.hasError();
+}
+
 bool Scribus150Format::readSections(ScribusDoc* doc, ScXmlStreamReader& reader)
 {
 	QStringRef tagName = reader.name();
@@ -3214,6 +3295,25 @@
 				doc->Items = DItems;
 			}
 		}
+		if (tName == "MARKER")
+		{
+			if (newItem->asTextFrame())
+			{
+				QString l = tAtt.valueAsString("label");
+				MarkerType t = (MarkerType) tAtt.valueAsInt("type");
+				Marker* mark = m_Doc->getMarkerDefinied(l, t);
+				if (mark == NULL)
+					qDebug() << "Undefinied marker label ["<< l << "] type " << t;
+				else
+				{
+					//set pointer to item holds marker in his text
+					if (t == MARKERAnchorType)
+						mark->setItemPtr(newItem);
+					mark->OwnPage = newItem->OwnPage;
+					newItem->itemText.insertMarker(mark, newItem->itemText.length());
+				}
+			}
+		}
 		if (tName == "WeldEntry")
 		{
 			PageItem::weldingInfo wInf;
@@ -4535,6 +4635,9 @@
 	itemNextF.clear();
 	WeldItems.clear();
 	WeldID.clear();
+	markeredItemsList.clear();
+	markeredMarkersList.clear();
+	
 
  	QString f(readSLA(fileName));
 	if (f.isEmpty())
@@ -5265,3 +5368,51 @@
 	*num2 = counter2;
 	return success;
 }
+
+void Scribus150Format::updateMarkersPtr() //after document load items pointers should be updated in markeredItemList
+{
+	if (!markeredItemsList.isEmpty())
+	{
+		QMap<QString,Marker*>::Iterator markIt;
+		for (markIt = markeredItemsList.begin(); markIt != markeredItemsList.end(); ++markIt)
+		{
+			QString itemName = markIt.key();
+			Marker* marker = markIt.value();
+			if (m_Doc->itemNameExists(itemName))
+			{
+				marker->setItemPtr(m_Doc->getItemFromName(itemName));
+				marker->setString(QString("%1").arg(marker->getItemPtr()->OwnPage +1));
+			}
+			else
+			{
+				qWarning() << "wrong marker [" << marker->label << "] data - item name [" << itemName << "] not exists - DELETING MARKER";
+				if (!m_Doc->eraseMarker(marker))
+					qWarning() << "Erase marker [" << marker->label << "] failed - was it definied?";
+			}
+		}
+	}
+	if (!markeredMarkersList.isEmpty())
+	{
+		QMap<Marker*,QMap<QString, MarkerType> >::iterator markIt;
+		for (markIt = markeredMarkersList.begin(); markIt != markeredMarkersList.end(); ++markIt)
+		{
+			Marker* mark = markIt.key();
+			QMap<QString, MarkerType> mark2map = markIt.value();
+			QString label2 = mark2map.begin().key();
+			MarkerType type2 = mark2map.begin().value();
+			Marker* mark2 = m_Doc->getMarkerDefinied(label2, type2);
+			if (mark2 != NULL)
+			{
+				mark->setMarker(mark2);
+				mark->setString(QString("%1").arg(mark2->getItemPtr()->OwnPage +1));
+			}
+			else
+			{
+				qWarning() << "wrong marker [" << mark->label << "] data - pointed merker name [" << label2 << "] not exists - DELETING MARKER";
+				if (!m_Doc->eraseMarker(mark))
+					qWarning() << "Erase marker [" << mark->label << "] failed - was it definied?";
+
+			}
+		}
+	}
+}
Index: scribus/scribus.h
===================================================================
--- scribus/scribus.h	(wersja 17181)
+++ scribus/scribus.h	(kopia robocza)
@@ -74,6 +74,7 @@
 class GuideManager;
 class HelpBrowser;
 class LayerPalette;
+class MarkersManager;
 class Measurements;
 class ScMWMenuManager;
 class ModeToolBar;
@@ -208,6 +209,7 @@
 	GuideManager *guidePalette;
 	CharSelect *charPalette;
 	PropertiesPalette *propertiesPalette;
+	MarkersManager *markersManager;
 	NodePalette *nodePalette;
 	OutlinePalette *outlinePalette;
 	Biblio *scrapbookPalette;
@@ -611,6 +613,20 @@
 	FormatsManager *formatsManager;
 
 	QPointer<HelpBrowser> helpBrowser;
+
+public slots:
+	//insert marker
+	void slotInsertMarker2Marker() { insertMarker(MARKER2MarkerType); }
+	void slotInsertMarkerAnchor() { insertMarker(MARKERAnchorType); }
+	void slotInsertMarkerVariableText() { insertMarker(MARKERVariableTextType); }
+	void slotInsertMarkerItem() { insertMarker(MARKER2ItemType); }
+	void slotInsertMarkerFootnote() { insertMarker(MARKERFootnoteType); }
+	void slotInsertMarkerEndnote() { insertMarker(MARKEREndnoteType); }
+	void slotInsertMarkerIndex() { insertMarker(MARKERIndexType); }
+	void slotEditMarker();
+	void slotUpdateMarkers();
+private:
+	void insertMarker(MarkerType);
 };
 
 #endif
Index: scribus/CMakeLists.txt
===================================================================
--- scribus/CMakeLists.txt	(wersja 17181)
+++ scribus/CMakeLists.txt	(kopia robocza)
@@ -85,6 +85,11 @@
   ui/inserttablerowsdialog.ui
   ui/latexeditor.ui
   ui/newmarginwidgetbase.ui
+ui/marker2item.ui
+ui/marker2marker.ui
+ui/markeranchor.ui
+ui/markervariabletext.ui
+ui/markersmanager.ui
   ui/measurementsbase.ui
   ui/multipleduplicate.ui
   ui/multiprogressdialog.ui
@@ -204,6 +209,7 @@
   latexhelpers.h
   loadsaveplugin.h
   menumanager.h
+markers.h
   navigator.h
   observable.h
   pageitem.h
@@ -310,6 +316,12 @@
   ui/latexeditor.h
   ui/layers.h
   ui/loremipsum.h
+ui/markerinsertdlgbase.h
+ui/marker2item.h
+ui/marker2marker.h
+ui/markeranchor.h
+ui/markervariabletext.h
+ui/markersmanager.h
   ui/margindialog.h
   ui/marginpresetlayout.h
   ui/marginwidget.h
@@ -734,6 +746,11 @@
   ui/linecombo.cpp
   ui/linkbutton.cpp
   ui/loremipsum.cpp
+ui/marker2item.cpp
+ui/marker2marker.cpp
+ui/markeranchor.cpp
+ui/markervariabletext.cpp
+ui/markersmanager.cpp
   ui/margindialog.cpp
   ui/marginpresetlayout.cpp
   ui/marginwidget.cpp
markers4.patch (88,046 bytes)   

jghali

2012-01-09 12:38

administrator   ~0027498

ui/marker2marker.h, ui/markeranchor.h, ui/markervariabletext.h still missing.

cbradney

2012-01-09 19:47

administrator   ~0027500

Cezary, its not that hard to get a patch right.. can you please upload a complete patch?

cezaryece

2012-01-10 10:05

updater   ~0027503

Damm it, fatum or what?
Maybe this time is all OK, here marker5.patch is working...

cezaryece

2012-01-10 10:06

updater  

markers5.patch (102,345 bytes)   
Index: scribus/scribusdoc.cpp
===================================================================
--- scribus/scribusdoc.cpp	(wersja 17188)
+++ scribus/scribusdoc.cpp	(kopia robocza)
@@ -100,6 +100,12 @@
 #include "colormgmt/sccolormgmtenginefactory.h"
 #include "ui/hruler.h"
 #include "ui/layers.h"
+#include "ui/markerinsertdlgbase.h"
+#include "ui/marker2item.h"
+#include "ui/marker2marker.h"
+#include "ui/markeranchor.h"
+#include "ui/markervariabletext.h"
+#include "ui/markersmanager.h"
 #include "ui/scmessagebox.h"
 #include "ui/storyeditor.h"
 
@@ -635,6 +641,11 @@
 			delete pa.items.takeFirst();
 		}
 	}
+	QList<Marker*> marks = markersMap.values();
+	for (int i =0; i < marks.count(); ++i)
+		delete marks[i];
+	marks.clear();
+	markersMap.clear();
 	docPatterns.clear();
 	docGradients.clear();
 	while (!DocItems.isEmpty())
@@ -14627,6 +14638,327 @@
 	}
 }
 
+Marker* ScribusDoc::getMarkerDefinied(QString l, MarkerType t)
+{
+	if (markersMap.contains(l))
+	{
+		QList<Marker*> mlist = markersMap.values(l);
+		QList<Marker*>::const_iterator i;
+		for (i = mlist.constBegin(); i != mlist.constEnd(); ++i)
+		{
+			if ((*i)->getType() == t)
+				return (*i);
+		}
+	}
+	return NULL;
+}
+
+PageItem* ScribusDoc::findMarker(Marker* marker, int &lastItem)
+{
+	lastItem++;
+	for (int a = lastItem; a < Items->count(); ++a)
+	{
+		PageItem* currItem = Items->at(a);
+		if (currItem->isTextFrame() && currItem->itemText.length() > 0)
+		{
+			for (int i = currItem->firstInFrame(); i < currItem->itemText.length(); i++)
+			{
+				ScText* hl = currItem->itemText.item(i);
+				if ((hl->ch == SpecialChars::OBJECT) && (hl->marker == marker))
+				{
+					lastItem = a;
+					return currItem;
+				}
+			}
+		}
+	}
+	lastItem = 0;
+	return NULL;
+}
+
+PageItem* ScribusDoc::findMarker(Marker* marker)
+{
+	int temp = -1;
+	return findMarker(marker,temp);
+}
+
+PageItem* ScribusDoc::findMarker(QString label, MarkerType type)
+{
+	return findMarker(getMarkerDefinied(label, type));
+}
+
+bool ScribusDoc::findMarkerCPos(Marker* marker, PageItem* &currItem, int &pos)
+{
+	if (currItem->isTextFrame() && currItem->itemText.length() > 0)
+	{
+		for (pos = currItem->firstInFrame(); pos < currItem->itemText.length(); pos++)
+		{
+			ScText* hl = currItem->itemText.item(pos);
+			if ((hl->ch == SpecialChars::OBJECT) && (hl->marker == marker))
+				return true;
+		}
+	}
+	return false;
+}
+
+bool ScribusDoc::eraseMarker(Marker *marker)
+{
+	bool found = false;
+	QMap<QString, Marker*>::Iterator mIt = markersMap.find(marker->label);
+	//find markers pointed to that marker
+	while (mIt != markersMap.end())
+	{
+		Marker* mrk = (Marker*) mIt.value();
+		if ((mrk->getType()==MARKER2MarkerType) && (mrk->getMarker() == marker))
+			mrk->setMarker(NULL);
+		mIt++;
+	}
+	//find and delete all marker`s apperences in text
+	int MPos;
+	PageItem* item = findMarker(marker);
+	int itemIndex;
+	while (item != NULL)
+	{
+		itemIndex = DocItems.indexOf(item);
+		while (findMarkerCPos(marker, item, MPos))
+		{
+			item->itemText.select(MPos,1);
+			item->asTextFrame()->deleteSelectedTextFromFrame();
+		}
+		found = true;
+		item->update();
+		item = findMarker(marker,itemIndex);
+	}
+	mIt = markersMap.find(marker->label);
+	while (mIt != markersMap.end())
+	{
+		Marker* mrk = (Marker*) mIt.value();
+		if (mrk == marker)
+		{
+			markersMap.erase(mIt);
+			break;
+		}
+		mIt++;
+	}
+	return found;
+}
+
+bool ScribusDoc::eraseMarker(QString label, MarkerType type)
+{
+	return eraseMarker(getMarkerDefinied(label, type));
+}
+
+void ScribusDoc::editMarkerDlg(Marker * marker)
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	QVector<Marker*> markerList;
+	for(markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+		Marker* mark = markIt.value();
+		markerList.push_back(mark);
+	}
+	MarkerInsertDlg* editMDialog = NULL;
+	switch (marker->getType())
+	{
+	case MARKERAnchorType:
+		editMDialog = (MarkerInsertDlg*) new MarkerAnchorDlg(scMW());
+		editMDialog->setValues(marker->label);
+		break;
+	case MARKERVariableTextType:
+		editMDialog = (MarkerInsertDlg*) new MarkerVariableTextDlg(markerList, false, scMW());
+		editMDialog->setValues(marker->label, marker->getString());
+		break;
+	case MARKER2ItemType:
+		editMDialog = (MarkerInsertDlg*) new Marker2ItemDlg(scMW());
+		editMDialog->setValues(marker->label, marker->getItemPtr());
+		break;
+	case MARKER2MarkerType:
+		editMDialog = (MarkerInsertDlg*) new Marker2MarkerDlg(markerList, marker, scMW());
+		editMDialog->setValues(marker->label, marker->getMarker());
+		break;
+	case MARKERFootnoteType:
+		break;
+	case MARKEREndnoteType:
+		break;
+	case MARKERIndexType:
+		break;
+	default:
+		break;
+	}
+	editMDialog->setWindowTitle(tr("Edit ") + editMDialog->windowTitle());
+	if (editMDialog->exec())
+	{
+		Marker* Mrk = NULL;
+		MarkerData d;
+		 d.strPtr = NULL;
+		 d.itemPtr = NULL;
+		 d.mrkPtr = NULL;
+		 d.itemName = "";
+		QString label = "", text = "";
+		QString oldStr = marker->getString();
+		switch (marker->getType())
+		{
+		case MARKERAnchorType:
+			//only gets label for new marker
+			editMDialog->values(label);
+			if (label.isEmpty() || getMarkerDefinied(label, MARKERAnchorType) != NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			marker->label = label;
+			break;
+		case MARKERVariableTextType:
+			Mrk = editMDialog->values(label, text);
+			if (label.isEmpty() || text.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (Mrk != NULL)
+				marker = Mrk;
+			marker->label = label;
+			if (text != oldStr)
+			{
+				marker->setString(text);
+				updateMarkerVariableText(marker, true);
+			}
+			break;
+		case MARKER2ItemType:
+			editMDialog->values(label, d.itemPtr);
+			if (label.isEmpty() || d.itemPtr == NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.itemPtr != marker->getItemPtr())
+			{
+				marker->setItemPtr(d.itemPtr);
+				marker->setString(QString("%1").arg(d.itemPtr->OwnPage +1));
+			}
+			marker->label = label;
+			break;
+		case MARKER2MarkerType:
+			//gets pointer to referenced marker
+			editMDialog->values(label, d.mrkPtr);
+			if ((d.mrkPtr == NULL) && label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.mrkPtr == NULL)
+			{
+				marker->setMarker(d.mrkPtr);
+				marker->setString("");
+			}
+			else if (d.mrkPtr != marker->getMarker())
+			{
+				marker->setMarker(d.mrkPtr);
+				marker->setString(QString("%1").arg(d.mrkPtr->OwnPage +1));
+			}
+			marker->label = label;
+		case MARKERFootnoteType:
+			break;
+		case MARKEREndnoteType:
+			break;
+		case MARKERIndexType:
+			break;
+		default:
+			break;
+		}
+		changed();
+	}
+	delete editMDialog;
+}
+
+void ScribusDoc::updateMarkerVariableText(Marker* marker, bool forceUpdate)
+{
+	if (marker->getType() == MARKERVariableTextType)
+	{
+		int itemNo = -1;
+		PageItem* mItem = findMarker(marker, itemNo);
+		while (mItem != NULL)
+		{
+			if (forceUpdate)
+				mItem->layout();
+			else
+			{
+				mItem->invalidateLayout();
+			}
+			mItem = findMarker(marker, itemNo);
+		}
+	}
+}
+
+void ScribusDoc::updateMarkers() //update strings (page number) for markers pointed to anchors and items
+{
+	if (isLoading())
+		return;
+	QMap<QString,Marker*>::Iterator markIt;
+	//for all markers
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		//set marker page number
+		PageItem* mItem = findMarker(marker);
+		if (mItem != NULL)
+			marker->OwnPage = mItem->OwnPage;
+		else
+			marker->OwnPage = -1;
+	}
+	QList<Marker*> toDeleting;
+	//run for update markers to items
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		if (marker->getType() == MARKER2ItemType)
+		{
+			if (marker->getItemPtr() == NULL)  //pointer to item not set
+			{
+				qWarning() << "Wrong marker [" << marker->label << "] to item data - no item pointer and no item name - DELETING IT";
+				toDeleting.append(marker);
+				continue;
+			}
+			int page = marker->getItemPtr()->OwnPage +1;
+			if (marker->getString().toInt() != page)
+			{
+				marker->setString(QString("%1").arg(page));
+				(findMarker(marker))->invalidateLayout();
+			}
+		}
+	}
+	//run for markers to markers
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+	{
+
+		Marker* marker = markIt.value();
+		if (marker->getType() == MARKER2MarkerType)
+		{
+			Marker* destMark = marker->getMarker();
+			if (destMark == NULL)
+			{
+				qWarning() << QString("Update markers2markers: marker %1 - destination marker is NULL").arg(marker->label);
+				toDeleting.append(marker);
+				continue;
+			}
+			PageItem* mItem = findMarker(destMark);
+			if (mItem == NULL)
+			{
+				destMark->OwnPage = -1;
+				marker->setString("");
+			}
+			else
+			{
+				destMark->OwnPage = (findMarker(destMark))->OwnPage;
+				int page = destMark->OwnPage +1;
+				if (marker->getString().toInt() != page)
+				{
+					marker->setString(QString("%1").arg(page));
+					(findMarker(marker))->invalidateLayout();
+				}
+			}
+		}
+	}
+	//run for variable text (invalidate frames with variable text)
+	for (markIt = markersMap.begin(); markIt != markersMap.end(); ++markIt)
+		updateMarkerVariableText(markIt.value(), false);
+	if (!toDeleting.isEmpty())
+	{
+		for (int i = 0; i < toDeleting.count(); i++)
+			eraseMarker(toDeleting.at(i));
+	}
+	scMW()->slotUpdateMarkers();
+	scMW()->markersManager->updateListView();
+}
+
 void ScribusDoc::itemSelection_UnWeld()
 {
 	PageItem *currItem;
Index: scribus/canvasmode_edit.cpp
===================================================================
--- scribus/canvasmode_edit.cpp	(wersja 17188)
+++ scribus/canvasmode_edit.cpp	(kopia robocza)
@@ -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())->marker != NULL))
+			{	//invoke edit marker dialog
+				m_ScMW->slotEditMarker();
+				return;
+			}
 			else
 			{	//Double click in a frame to select a word
 				oldCp = currItem->itemText.cursorPosition();
Index: scribus/sctextstruct.h
===================================================================
--- scribus/sctextstruct.h	(wersja 17188)
+++ scribus/sctextstruct.h	(kopia robocza)
@@ -28,6 +28,7 @@
 #include "styles/paragraphstyle.h"
 
 class PageItem;
+class Marker;
 
 /* Struktur fuer Pageitem Text */
 
@@ -116,7 +117,6 @@
 	InlineFrameData* d;
 };
 
-
 #ifndef NLS_PROTO
 class SCRIBUS_API ScText : public CharStyle
 {
@@ -128,16 +128,17 @@
 	float PRot;
 	float PDx;
 	InlineFrame embedded;
+	Marker* marker;
 	QChar ch;
 	ScText() : 
 		CharStyle(),
 		parstyle(NULL), glyph(), 
-		PtransX(0.0f), PtransY(0.0f), PRot(0.0f), PDx(0.0f), embedded(NULL), ch() {}
+		PtransX(0.0f), PtransY(0.0f), PRot(0.0f), PDx(0.0f), embedded(NULL), marker(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), marker(other.marker), ch(other.ch)
 	{
 		glyph.more = NULL;
 		GlyphLayout *layout = &glyph;
Index: scribus/pageitem.h
===================================================================
--- scribus/pageitem.h	(wersja 17188)
+++ scribus/pageitem.h	(kopia robocza)
@@ -237,15 +237,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();
Index: scribus/pageitem.cpp
===================================================================
--- scribus/pageitem.cpp	(wersja 17188)
+++ scribus/pageitem.cpp	(kopia robocza)
@@ -41,6 +41,7 @@
 #include "cmsettings.h"
 #include "colorblind.h"
 #include "commonstrings.h"
+#include "markers.h"
 
 #include "pageitem_group.h"
 #include "pageitem_textframe.h"
@@ -825,6 +826,20 @@
 	isInlineImage = false;
 }
 
+PageItem::~PageItem()
+{
+	if (tempImageFile != NULL)
+		delete tempImageFile;
+	//delete markers pointed to that item
+	QMap<QString,Marker*>::Iterator markIt;
+	for (markIt = doc()->markersMap.begin(); markIt != doc()->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		if ((marker->getType() == MARKER2ItemType) && (marker->getItemPtr() == this))
+			doc()->eraseMarker(marker);
+	}
+}
+
 void PageItem::setXPos(const double newXPos, bool drawingOnly)
 {
 	Xpos = newXPos;
@@ -2223,6 +2238,15 @@
 		else
 			return "%";
 	}
+	//check for markers
+	else if (ch == SpecialChars::OBJECT)
+	{
+		ScText* hl = itemText.item(base);
+		if (hl->marker != NULL && hl->marker->getType() != MARKERAnchorType && hl->marker->getType() != MARKERIndexType)
+		{
+			chstr = hl->marker->getString();
+		}
+	}
 	return chstr;
 }
 
@@ -2406,6 +2430,12 @@
 			points.addQuadPoint(0, -10, 0, -10, 0, -6, 0, -6);
 			stroke = true;
 		}
+		else if (glyph == SpecialChars::OBJECT.unicode())
+		{
+			points.resize(0);
+			points.addQuadPoint(0, -8, 1, -8, 0, -6, 1, -6);
+			stroke = true;
+		}
 		else // ???
 		{
 			points.resize(0);
Index: scribus/scribusdoc.h
===================================================================
--- scribus/scribusdoc.h	(wersja 17188)
+++ scribus/scribusdoc.h	(kopia robocza)
@@ -40,6 +40,7 @@
 #include "scribusapi.h"
 #include "colormgmt/sccolormgmtengine.h"
 #include "documentinformation.h"
+#include "markers.h"
 #include "observable.h"
 #include "pageitem.h"
 #include "pagestructs.h"
@@ -72,7 +73,7 @@
 class ScPattern;
 class UndoTransaction;
 class Serializer;
-
+class MarkersManager;
 class QProgressBar;
 
 struct SCRIBUS_API NodeEditContext : public MassObservable<QPointF>
@@ -1259,7 +1260,7 @@
 	MassObservable<ScPage*> m_pagesChanged;
 	MassObservable<QRectF> m_regionsChanged;
 	DocUpdater* m_docUpdater;
-	
+
 signals:
 	//Lets make our doc talk to our GUI rather than confusing all our normal stuff
 	/**
@@ -1520,8 +1521,24 @@
 	void updatePict(QString name);
 	void updatePictDir(QString name);
 	void removePict(QString name);
-//welding two items
+// Markers
+public:
+	//list of markers with its lables as keys
+	QMap<QString, Marker*> markersMap;
+	Marker* getMarkerDefinied(QString label, MarkerType type); //returns marker with label and type (labels are unique only for same type markers)
+	PageItem* findMarker(Marker* marker, int &lastItem);
+	PageItem* findMarker(Marker* marker);
+	PageItem* findMarker(QString label, MarkerType type);
+	bool findMarkerCPos(Marker* marker, PageItem* &item, int &CPos);
+	bool eraseMarker(QString label, MarkerType type);
+	bool eraseMarker(Marker* marker);
+	void editMarkerDlg(Marker*);
+	void updateMarkerVariableText(Marker* marker, bool forceUpdate = false); //returns if any text was changed
 public slots:
+	void updateMarkers(); //update strings (page number) for markers pointed to anchors and items
+
+	//welding two items
+public slots:
 	void itemSelection_UnWeld();
 	void itemSelection_Weld();
 	void itemSelection_EditWeld();
Index: scribus/actionmanager.cpp
===================================================================
--- scribus/actionmanager.cpp	(wersja 17188)
+++ scribus/actionmanager.cpp	(kopia robocza)
@@ -240,8 +240,11 @@
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 	name="editJavascripts";
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	name="editMarkers";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 
 	(*scrActions)["editStyles"]->setToggleAction(true);
+	(*scrActions)["editMarkers"]->setToggleAction(true);
 
 	connect( (*scrActions)["editUndoAction"], SIGNAL(triggeredData(int)) , undoManager, SLOT(undo(int)) );
 	connect( (*scrActions)["editRedoAction"], SIGNAL(triggeredData(int)) , undoManager, SLOT(redo(int)) );
@@ -540,10 +543,45 @@
 	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
 	(*scrActions)["stickyTools"]->setToggleAction(true);
 
+	//Markers
+	name="insertMarkerAnchor";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarkerVariableText";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarkerItem";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+	name="insertMarker2Marker";
+	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+	(*scrActions)[name]->setEnabled(true);
+//	name="insertMarkerFootnote";
+//	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+//	(*scrActions)[name]->setEnabled(true);
+//	name="insertMarkerEndnote";
+//	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+//	(*scrActions)[name]->setEnabled(true);
+//	name="insertMarkerIndex";
+//	scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow));
+//	(*scrActions)[name]->setEnabled(true);
+	name="editMarker";
+	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)["insertMarkerAnchor"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerAnchor()) );
+	connect( (*scrActions)["insertMarkerVariableText"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerVariableText()) );
+	connect( (*scrActions)["insertMarkerItem"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerItem()) );
+	connect( (*scrActions)["insertMarker2Marker"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarker2Marker()) );
+//	connect( (*scrActions)["insertMarkerFootnote"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerFootnote()) );
+//	connect( (*scrActions)["insertMarkerEndnote"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerEndnote()) );
+//	connect( (*scrActions)["insertMarkerIndex"], SIGNAL(triggered()), mainWindow, SLOT(slotInsertMarkerIndex()) );
+	connect( (*scrActions)["editMarker"], SIGNAL(triggered()), mainWindow, SLOT(slotEditMarker()) );
 }
 
 void ActionManager::initPageMenuActions()
@@ -1391,6 +1429,7 @@
 //	(*scrActions)["editPatterns"]->setTexts( tr("Patterns..."));
 //	(*scrActions)["editGradients"]->setTexts( tr("Gradients..."));
 	(*scrActions)["editStyles"]->setTexts( tr("S&tyles..."));
+	(*scrActions)["editMarkers"]->setTexts( tr("Markers..."));
 	(*scrActions)["editMasterPages"]->setTexts( tr("&Master Pages..."));
 	(*scrActions)["editJavascripts"]->setTexts( tr("&JavaScripts..."));
 
@@ -1485,6 +1524,14 @@
 	(*scrActions)["insertGlyph"]->setTexts( tr("&Glyph..."));
 	(*scrActions)["insertSampleText"]->setTexts( tr("Sample Text"));
 	(*scrActions)["stickyTools"]->setTexts( tr("Sticky Tools"));
+	(*scrActions)["insertMarkerAnchor"]->setTexts( tr("Anchor Marker"));
+	(*scrActions)["insertMarkerVariableText"]->setTexts( tr("Variable Text"));
+	(*scrActions)["insertMarkerItem"]->setTexts( tr("Reference to Item"));
+	(*scrActions)["insertMarker2Marker"]->setTexts( tr("Reference to Anchor Marker"));
+//	(*scrActions)["insertMarkerFootnote"]->setTexts( tr("Footnote"));
+//	(*scrActions)["insertMarkerEndnote"]->setTexts( tr("Endnote"));
+//	(*scrActions)["insertMarkerIndex"]->setTexts( tr("Index entry"));
+	(*scrActions)["editMarker"]->setTexts( tr("Edit Marker"));
 
 	//Page menu
 	(*scrActions)["pageInsert"]->setTexts( tr("&Insert..."));
@@ -1873,6 +1920,7 @@
 		<< "editReplaceColors"
 //		<< "editPatterns"
 		<< "editStyles"
+		<< "editMarkers"
 		<< "editMasterPages"
 		<< "editJavascripts";
 	//Style
@@ -1978,7 +2026,15 @@
 		<< "toolsInsertRenderFrame"
 		<< "stickyTools"
 		<< "insertGlyph"
-		<< "insertSampleText";
+		<< "insertSampleText"
+		<< "insertMarkerAnchor"
+		<< "insertMarkerVariableText"
+		<< "insertMarkerItem"
+		<< "insertMarker2Marker"
+//		<< "insertMarkerFootnote"
+//		<< "insertMarkerEndnote"
+//		<< "insertMarkerIndex"
+		<< "editMarker";
 
 	itmenu->second
 		<< "unicodeSoftHyphen"
Index: scribus/pageitem_textframe.cpp
===================================================================
--- scribus/pageitem_textframe.cpp	(wersja 17188)
+++ scribus/pageitem_textframe.cpp	(kopia robocza)
@@ -34,7 +34,9 @@
 
 #include "canvas.h"
 #include "commonstrings.h"
+#include "fonts/scface.h"
 #include "hyphenator.h"
+#include "markers.h"
 #include "pageitem.h"
 #include "pageitem_group.h"
 #include "pageitem_textframe.h"
@@ -53,6 +55,12 @@
 #include "util.h"
 #include "util_math.h"
 
+#include "ui/markerinsertdlgbase.h"
+#include "ui/marker2item.h"
+#include "ui/marker2marker.h"
+#include "ui/markeranchor.h"
+#include "ui/markervariabletext.h"
+#include "ui/markersmanager.h"
 #include "ui/guidemanager.h"
 
 #include <cairo.h>
@@ -1392,6 +1400,15 @@
 		for (int a = firstInFrame(); a < itemText.length(); ++a)
 		{
 			hl = itemText.item(a);
+			if (hl->ch == SpecialChars::OBJECT && hl->marker != NULL)
+			{
+				hl->glyph.glyph = SpecialChars::OBJECT.unicode() + ScFace::CONTROL_GLYPHS;
+				if (hl->marker->getType() == MARKERAnchorType || hl->marker->getType() == MARKERIndexType)
+				{
+					hl->glyph.shrink();
+					continue;
+				}
+			}
 			if (a > 0 && itemText.text(a-1) == SpecialChars::PARSEP)
 				style = itemText.paragraphStyle(a);
 			if (current.itemsInLine == 0)
@@ -1525,8 +1542,12 @@
 				// 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 = charStyle.font().realCharHeight(chstr[0], 1);
-				double realCharAscent = charStyle.font().realCharAscent(chstr[0], 1);
+				double realCharHeight = 0.0, realCharAscent = 0.0;
+				for (int i = 0; i < chstr.length(); i++)
+				{
+					realCharHeight = qMax(realCharHeight, charStyle.font().realCharHeight(chstr[i], 1));
+					realCharAscent = qMax(realCharAscent, charStyle.font().realCharAscent(chstr[i], 1));
+				}
 				double fontAscent     = charStyle.font().ascent(style.charStyle().fontSize() / 10.0);
 				if (realCharHeight == 0.0)
 					realCharHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
@@ -1591,11 +1612,19 @@
 				}
 				else
 				{
-					double realCharHeight = charStyle.font().realCharHeight(chstr[0], charStyle.fontSize() / 10.0);
+					double realCharHeight = 0.0;
+					wide = 0.0; realAsce = 0.0;
+					//
+					for (int i = 0; i < chstr.length(); i++)
+					{
+						realCharHeight = qMax(realCharHeight, charStyle.font().realCharHeight(chstr[i], charStyle.fontSize() / 10.0));
+						realAsce = qMax(realAsce, charStyle.font().realCharHeight(chstr[i], chsd / 10.0));
+						wide += charStyle.font().realCharWidth(chstr[i], chsd / 10.0);
+					}
+					wide = (wide* scaleH) + (1 - scaleH);
+					realAsce = realAsce  * scaleV + offset;
 					if (realCharHeight == 0)
 						realCharHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
-					wide = (charStyle.font().realCharWidth(chstr[0], chsd / 10.0) * scaleH) + (1 - scaleH); //dropcaps are to close to next glyphs if glyphs are hard scaled
-					realAsce = charStyle.font().realCharHeight(chstr[0], chsd / 10.0) * scaleV + offset;
 					asce = charStyle.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;
@@ -1619,12 +1648,19 @@
 					desc = realDesc = 0;
 				else
 				{
+					for (int i = 0; i < chstr.length(); i++)
+					{
+						if (chstr[i] == SpecialChars::OBJECT)
+							continue;
+						realDesc = qMax(realDesc, charStyle.font().realCharDescent(chstr[i], hlcsize10));
+						realAsce = charStyle.font().realCharAscent(chstr[i], hlcsize10);
+					}
+					realDesc =  realDesc * scaleV - offset;
 					desc = -charStyle.font().descent(hlcsize10);
-					realDesc = charStyle.font().realCharDescent(chstr[0], hlcsize10) * scaleV - offset;
 					current.rememberShrinkStretch(hl->ch, wide, style);
 				}
 				asce = charStyle.font().ascent(hlcsize10);
-				realAsce = charStyle.font().realCharAscent(chstr[0], hlcsize10) * scaleV + offset;
+				realAsce = realAsce * scaleV + offset;
 			}
 
 			//check for Y position at beginning of line
@@ -1935,7 +1971,12 @@
 			
 			// remember y pos
 			if (DropCmode)
-				hl->glyph.yoffset -= charStyle.font().realCharHeight(chstr[0], chsd / 10.0) - charStyle.font().realCharAscent(chstr[0], chsd / 10.0);
+			{
+				double yoffset = 0.0;
+				for (int i = 0; i < chstr.length(); i++)
+					yoffset = qMax(yoffset, charStyle.font().realCharHeight(chstr[i], chsd / 10.0) - charStyle.font().realCharAscent(chstr[i], chsd / 10.0));
+				hl->glyph.yoffset -= yoffset;
+			}
 			
 			// remember x pos
 			double breakPos = current.xPos;
@@ -2771,11 +2812,13 @@
 			{
 				bool selecteds = itemText.selected(as);
 				hls = itemText.item(as);
+				if (hls->marker != NULL && (hls->marker->getType() == MARKERAnchorType || hls->marker->getType() == MARKERIndexType))
+					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()) && (hls->ch == SpecialChars::OBJECT && hls->embedded.hasItem()))
 					    || previousWasObject)
 					{
 						sFList << selectedFrame;
@@ -2792,7 +2835,7 @@
 							asce = charStyleS.font().ascent(charStyleS.fontSize() / 10.0);
 							wide = hls->glyph.wide();
 							QRectF scr;
-							if ((hls->ch == SpecialChars::OBJECT)  && (hls->embedded.hasItem()))
+							if (hls->ch == SpecialChars::OBJECT && hls->embedded.hasItem())
 							{
 								double ww = (hls->embedded.getItem()->gWidth + hls->embedded.getItem()->lineWidth()) * hls->glyph.scaleH;
 								double hh = (hls->embedded.getItem()->gHeight + hls->embedded.getItem()->lineWidth()) * hls->glyph.scaleV;
@@ -4031,3 +4074,231 @@
 {
 	invalidateLayout();
 }
+
+void PageItem_TextFrame::insertMarkerDlg(MarkerType markerType)
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	QVector<Marker*> markerList;
+	for (markIt = m_Doc->markersMap.begin(); markIt != m_Doc->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		markerList.push_back(marker);
+	}
+	MarkerInsertDlg* insertMDialog = NULL;
+	switch (markerType)
+	{
+	case MARKERAnchorType:
+		insertMDialog = (MarkerInsertDlg*) new MarkerAnchorDlg(m_Doc->scMW());
+		break;
+	case MARKERVariableTextType:
+		insertMDialog = (MarkerInsertDlg*) new MarkerVariableTextDlg(markerList, true, m_Doc->scMW());
+		break;
+	case MARKER2ItemType:
+		insertMDialog = (MarkerInsertDlg*) new Marker2ItemDlg(m_Doc->scMW());
+		break;
+	case MARKER2MarkerType:
+		insertMDialog = (MarkerInsertDlg*) new Marker2MarkerDlg(markerList, NULL, m_Doc->scMW());
+		break;
+	case MARKERFootnoteType:
+		break;
+	case MARKEREndnoteType:
+		break;
+	case MARKERIndexType:
+		break;
+	}
+	if (insertMDialog == NULL)
+	{
+		qDebug() << "Dialog not implemented for markers type " << markerType;
+		return;
+	}
+	insertMDialog->setWindowTitle(tr("Insert new ") + insertMDialog->windowTitle());
+	if (insertMDialog->exec())
+	{
+		Marker* Mrk = NULL;
+		MarkerData d;
+		 d.strPtr = NULL;
+		 d.itemPtr = NULL;
+		 d.mrkPtr = NULL;
+		QString label = "", text = "";
+		switch (markerType)
+		{
+		case MARKERAnchorType:
+			//only gets label for new marker
+			insertMDialog->values(label);
+			if (label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.itemPtr = this;
+			break;
+		case MARKERVariableTextType:
+			Mrk = insertMDialog->values(label, text);
+			if ((Mrk == NULL) && (label.isEmpty() || text.isEmpty()))
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.strPtr = new QString(text);
+			break;
+		case MARKER2ItemType:
+			insertMDialog->values(label, d.itemPtr);
+			if (d.itemPtr == NULL || label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.strPtr = new QString(QString::number(d.itemPtr->OwnPage +1));
+			break;
+		case MARKER2MarkerType:
+			//gets pointer to referenced marker
+			insertMDialog->values(label, d.mrkPtr);
+			if (d.mrkPtr == NULL || label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			d.strPtr = new QString(QString::number(d.mrkPtr->OwnPage +1));
+		case MARKERFootnoteType:
+			break;
+		case MARKEREndnoteType:
+			break;
+		case MARKERIndexType:
+			break;
+		}
+		//check if marker with such label exist already
+		if (markerType != MARKERVariableTextType && m_Doc->getMarkerDefinied(label, markerType) != NULL)
+			return; //FIX ME here user should be warned that inserting of marker fails and why
+
+		if (Mrk == NULL)
+		{
+			Mrk = new Marker;
+			Mrk->setValues(label, OwnPage, markerType, d);
+			m_Doc->markersMap.insert(label,Mrk);
+		}
+		else
+		{ // that must be variable text marker
+			Mrk->setStrPtr(d.strPtr);
+			m_Doc->updateMarkerVariableText(Mrk, true);
+		}
+		itemText.insertMarker(Mrk);
+		Mrk->OwnPage = OwnPage;
+		update();
+		m_Doc->changed();
+	}
+	delete insertMDialog;
+	m_Doc->scMW()->markersManager->updateListView();
+}
+
+void PageItem_TextFrame::editMarkerDlg(Marker * marker)
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	QVector<Marker*> markerList;
+	for(markIt = m_Doc->markersMap.begin(); markIt != m_Doc->markersMap.end(); ++markIt)
+	{
+		Marker* mark = markIt.value();
+		markerList.push_back(mark);
+	}
+	MarkerInsertDlg* editMDialog = NULL;
+	switch (marker->getType())
+	{
+	case MARKERAnchorType:
+		editMDialog = (MarkerInsertDlg*) new MarkerAnchorDlg(m_Doc->scMW());
+		editMDialog->setValues(marker->label);
+		break;
+	case MARKERVariableTextType:
+		editMDialog = (MarkerInsertDlg*) new MarkerVariableTextDlg(markerList, true, m_Doc->scMW());
+		editMDialog->setValues(marker->label, marker->getString());
+		break;
+	case MARKER2ItemType:
+		editMDialog = (MarkerInsertDlg*) new Marker2ItemDlg(m_Doc->scMW());
+		editMDialog->setValues(marker->label, marker->getItemPtr());
+		break;
+	case MARKER2MarkerType:
+		editMDialog = (MarkerInsertDlg*) new Marker2MarkerDlg(markerList, marker, m_Doc->scMW());
+		editMDialog->setValues(marker->label, marker->getMarker());
+		break;
+	case MARKERFootnoteType:
+		break;
+	case MARKEREndnoteType:
+		break;
+	case MARKERIndexType:
+		break;
+	default:
+		break;
+	}
+	editMDialog->setWindowTitle(tr("Edit ") + editMDialog->windowTitle());
+	if (editMDialog->exec())
+	{
+		Marker* Mrk = NULL;
+		MarkerData d;
+		 d.strPtr = NULL;
+		 d.itemPtr = NULL;
+		 d.mrkPtr = NULL;
+		 d.itemName = "";
+		QString label = "", text = "";
+		QString oldStr = marker->getString();
+		switch (marker->getType())
+		{
+		case MARKERAnchorType:
+			//only gets label for new marker
+			editMDialog->values(label);
+			if (label.isEmpty() || m_Doc->getMarkerDefinied(label, MARKERAnchorType) != NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			marker->label = label;
+			break;
+		case MARKERVariableTextType:
+			Mrk = editMDialog->values(label, text);
+			if ((Mrk == NULL) && (label.isEmpty() || text.isEmpty()))
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (Mrk != NULL)
+			{
+				if (Mrk != marker)
+				{
+					ScText* hl = itemText.item(itemText.cursorPosition());
+					hl->marker = Mrk;
+					marker = Mrk;
+				}
+				marker->label = label;
+				if (text != oldStr)
+				{
+					marker->setString(text);
+					if (marker->getString() != oldStr)
+						m_Doc->updateMarkerVariableText(marker, true);
+				}
+			}
+			else
+			{
+				d.strPtr = new QString(text);
+				Mrk = new Marker;
+				Mrk->setValues(label, OwnPage, MARKERVariableTextType, d);
+				m_Doc->markersMap.insert(label,Mrk);
+				ScText* hl = itemText.item(itemText.cursorPosition());
+				hl->marker = Mrk;
+			}
+			break;
+		case MARKER2ItemType:
+			editMDialog->values(label, d.itemPtr);
+			if (label.isEmpty() || d.itemPtr == NULL)
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.itemPtr != marker->getItemPtr())
+			{
+				marker->setItemPtr(d.itemPtr);
+				marker->setString(QString("%1").arg(d.itemPtr->OwnPage +1));
+			}
+			marker->label = label;
+			break;
+		case MARKER2MarkerType:
+			//gets pointer to referenced marker
+			editMDialog->values(label, d.mrkPtr);
+			if ((d.mrkPtr == NULL) && label.isEmpty())
+				return; //FIX ME here user should be warned that inserting of marker fails and why
+			if (d.mrkPtr != marker->getMarker())
+			{
+				marker->setMarker(d.mrkPtr);
+				marker->setString(QString("%1").arg(d.mrkPtr->OwnPage +1));
+			}
+			marker->label = label;
+		case MARKERFootnoteType:
+			break;
+		case MARKEREndnoteType:
+			break;
+		case MARKERIndexType:
+			break;
+		default:
+			break;
+		}
+		update();
+		m_Doc->changed();
+		m_Doc->scMW()->markersManager->updateListView();
+	}
+	delete editMDialog;
+}
Index: scribus/ui/markersmanager.ui
===================================================================
--- scribus/ui/markersmanager.ui	(wersja 0)
+++ scribus/ui/markersmanager.ui	(wersja 0)
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MarkersManager</class>
+ <widget class="QDialog" name="MarkersManager">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>253</width>
+    <height>249</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>200</width>
+    <height>100</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <property name="modal">
+   <bool>false</bool>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QListWidget" name="listView">
+     <property name="editTriggers">
+      <set>QAbstractItemView::DoubleClicked</set>
+     </property>
+     <property name="showDropIndicator" stdset="0">
+      <bool>false</bool>
+     </property>
+     <property name="selectionMode">
+      <enum>QAbstractItemView::NoSelection</enum>
+     </property>
+     <property name="selectionBehavior">
+      <enum>QAbstractItemView::SelectItems</enum>
+     </property>
+     <property name="horizontalScrollMode">
+      <enum>QAbstractItemView::ScrollPerPixel</enum>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QPushButton" name="UpdateButton">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="text">
+      <string>Update All Markers</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QSplitter" name="splitter">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <widget class="QPushButton" name="EditButton">
+      <property name="text">
+       <string>Edit</string>
+      </property>
+     </widget>
+     <widget class="QPushButton" name="DeleteButton">
+      <property name="text">
+       <string>Delete</string>
+      </property>
+     </widget>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
Index: scribus/ui/markersmanager.cpp
===================================================================
--- scribus/ui/markersmanager.cpp	(wersja 0)
+++ scribus/ui/markersmanager.cpp	(wersja 0)
@@ -0,0 +1,197 @@
+#include "markersmanager.h"
+#include "prefsmanager.h"
+#include "prefsfile.h"
+#include "scribus.h"
+#include "scribusdoc.h"
+#include <QStandardItemModel>
+
+MarkersManager::MarkersManager(QWidget *parent, const char *name)
+	: ScrPaletteBase(parent, name), m_doc(NULL)
+{
+	setupUi(this);
+	listView->setSelectionMode(QAbstractItemView::SingleSelection);
+	QString pname(name);
+	if (pname.isEmpty())
+		pname = "markersManager";
+	m_prefs = PrefsManager::instance()->prefsFile->getContext(pname);
+	setDoc(0);
+	languageChange();
+	EditButton->setEnabled(false);
+	DeleteButton->setEnabled(false);
+}
+
+MarkersManager::~MarkersManager()
+{
+	m_prefs->set("InitX", x());
+	m_prefs->set("InitY", y());
+	storeVisibility(this->isVisible());
+	storePosition();
+}
+
+void MarkersManager::changeEvent(QEvent *e)
+{
+	QDialog::changeEvent(e);
+	switch (e->type()) {
+		case QEvent::LanguageChange:
+			retranslateUi(this);
+			languageChange();
+			break;
+		default:
+			QWidget::changeEvent(e);
+			break;
+	}
+}
+
+void MarkersManager::hideEvent(QHideEvent *e)
+{
+	m_prefs->set("InitX", x());
+	m_prefs->set("InitY", y());
+	storeVisibility(false);
+	storePosition();
+	ScrPaletteBase::hideEvent(e);
+}
+
+void MarkersManager::closeEvent(QCloseEvent *e)
+{
+	m_prefs->set("InitX", x());
+	m_prefs->set("InitY", y());
+	storeVisibility(false);
+	storePosition();
+	ScrPaletteBase::closeEvent(e);
+}
+
+void MarkersManager::showEvent(QShowEvent *e)
+{
+	static bool isFirst = true;
+	ScrPaletteBase::showEvent(e);
+	if (isFirst)
+	{
+		QPoint p(m_prefs->getInt("InitX", x()), m_prefs->getInt("InitY", y()));
+		move(p);
+		isFirst = false;
+	}
+}
+
+void MarkersManager::addListItem(MarkerType typeMrk, QString typeStr, QVector<Marker*> &markers, int &index)
+{
+	bool noSuchMarkers = true;
+	QListWidgetItem *listItem = new QListWidgetItem(listView);
+	listItem->setText(typeStr);
+	listItem->setData(Qt::UserRole, QVariant::fromValue<void*>(NULL));
+	listItem->setFlags(listItem->flags() & (~Qt::ItemIsSelectable));
+	listItem->setBackgroundColor(QColor("lightGray"));
+	for (int i = 0; i < markers.size(); ++i)
+	{
+		if (markers[i]->getType() == typeMrk)
+		{
+			QListWidgetItem *listItem2 = new QListWidgetItem(listView);
+			listItem2->setText(markers[i]->label);
+			listItem2->setData(Qt::UserRole,QVariant::fromValue<void*>(markers[i]));
+			index++;
+			noSuchMarkers = false;
+		}
+	}
+	if (noSuchMarkers)
+	{
+		listView->removeItemWidget(listItem);
+		delete listItem;
+	}
+}
+
+void MarkersManager::updateListView()
+{
+	listView->clear();
+	if (m_doc == NULL)
+		return;
+	QMap<QString,Marker*>::Iterator markIt;
+	QVector<Marker*> markers;
+	for (markIt = m_doc->markersMap.begin(); markIt != m_doc->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		markers.push_back(marker);
+	}
+	if (markers.isEmpty())
+		UpdateButton->setEnabled(false);
+	else
+	{
+		UpdateButton->setEnabled(true);
+		int index = 0;
+		addListItem(MARKERAnchorType, tr("Anchors"), markers, index);
+		addListItem(MARKERVariableTextType, tr("Variable Text"), markers, index);
+		addListItem(MARKER2ItemType, tr("Markers to Items"), markers, index);
+		addListItem(MARKER2MarkerType, tr("Markers to Anchors"), markers, index);
+	//	addListItem(MARKERFootnoteType, tr("Footnote markers"), markers, index);
+	//	addListItem(MARKEREndnoteType, tr("Endnote markers");, markers, index);
+	//	addListItem(MARKERIndexType, tr("Index entries");, markers, index);
+	}
+}
+
+void MarkersManager::setDoc(ScribusDoc *doc)
+{
+	bool hasDoc = (doc != NULL);
+	m_doc = doc;
+	listView->setEnabled(hasDoc);
+	updateListView();
+}
+
+void MarkersManager::languageChange()
+{
+	setWindowTitle(tr("Markers Manager"));
+	listView->setToolTip(tr("Select Marker"));
+	UpdateButton->setText(tr("Update All Markers"));
+	UpdateButton->setToolTip(tr("Update all reference texts for all markers"));
+	EditButton->setText(tr("Edit"));
+	EditButton->setToolTip(tr("Edit selected marker"));
+	updateListView();
+}
+
+Marker* MarkersManager::getMarkerFromListView()
+{
+	QListWidgetItem* selectedItem = listView->currentItem();
+	Marker* marker = reinterpret_cast<Marker*>(selectedItem->data(Qt::UserRole).value<void*>());
+	return marker;
+}
+
+void MarkersManager::on_UpdateButton_clicked()
+{
+	m_doc->scMW()->slotUpdateMarkers();
+	m_doc->changed();
+	updateListView();
+}
+
+void MarkersManager::on_EditButton_clicked()
+{
+	Marker* marker = getMarkerFromListView();
+	if (marker != NULL)
+	{
+		m_doc->editMarkerDlg(marker);
+		updateListView();
+	}
+}
+
+void MarkersManager::on_DeleteButton_clicked()
+{
+	Marker* marker = getMarkerFromListView();
+	if (marker != NULL)
+	{
+		m_doc->eraseMarker(marker);
+		updateListView();
+	}
+}
+
+void MarkersManager::on_listView_doubleClicked(const QModelIndex &index)
+{
+	Marker* marker = getMarkerFromListView();
+	if (marker != NULL)
+	{
+		m_doc->editMarkerDlg(marker);
+		updateListView();
+	}
+}
+
+void MarkersManager::on_listView_itemSelectionChanged()
+{
+	bool isMarker = (getMarkerFromListView() != NULL);
+	EditButton->setEnabled(isMarker);
+	DeleteButton->setEnabled(isMarker);
+}
Index: scribus/ui/marker2item.cpp
===================================================================
--- scribus/ui/marker2item.cpp	(wersja 0)
+++ scribus/ui/marker2item.cpp	(wersja 0)
@@ -0,0 +1,43 @@
+#include "marker2item.h"
+#include "scribus.h"
+
+Marker2ItemDlg::Marker2ItemDlg(QWidget *parent) : MarkerInsertDlg(parent)
+{
+	setupUi(this);
+	ScribusMainWindow* scmw = (ScribusMainWindow*) parent;
+	QStringList itemsList;
+
+	for (int i = 0; i < scmw->doc->Items->count(); i++)
+		itemsList.append(scmw->doc->Items->at(i)->itemName());
+	ItemList->addItems(itemsList);
+	setWindowTitle(tr("Marker to Item"));
+}
+
+void Marker2ItemDlg::values(QString &label, PageItem* &ptr)
+{
+	QString itemName = ItemList->currentText();
+	if (itemName != "")
+	{
+		ScribusMainWindow* scmw = (ScribusMainWindow*) parent();
+		ptr = scmw->doc->getItemFromName(itemName);
+		label = labelEdit->text();
+	}
+}
+
+void Marker2ItemDlg::setValues(const QString label, const PageItem* ptr)
+{
+	ItemList->setCurrentIndex(ItemList->findText(ptr->itemName()));
+	labelEdit->setText(label);
+}
+
+void Marker2ItemDlg::changeEvent(QEvent *e)
+{
+    QDialog::changeEvent(e);
+    switch (e->type()) {
+    case QEvent::LanguageChange:
+        retranslateUi(this);
+        break;
+    default:
+        break;
+    }
+}
Index: scribus/ui/marker2marker.ui
===================================================================
--- scribus/ui/marker2marker.ui	(wersja 0)
+++ scribus/ui/marker2marker.ui	(wersja 0)
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Marker2MarkerDlg</class>
+ <widget class="QDialog" name="Marker2MarkerDlg">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>362</width>
+    <height>103</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>0</width>
+    <height>103</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>103</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QSplitter" name="splitter">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <widget class="QLabel" name="label_2">
+      <property name="text">
+       <string>Label:</string>
+      </property>
+     </widget>
+     <widget class="QLineEdit" name="labelEdit"/>
+    </widget>
+   </item>
+   <item>
+    <widget class="QSplitter" name="splitter_2">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <widget class="QLabel" name="label">
+      <property name="text">
+       <string>Select marker:</string>
+      </property>
+     </widget>
+     <widget class="QComboBox" name="LabelList">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="editable">
+       <bool>false</bool>
+      </property>
+      <property name="currentIndex">
+       <number>-1</number>
+      </property>
+      <property name="duplicatesEnabled">
+       <bool>false</bool>
+      </property>
+     </widget>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>166</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="buttonBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>Marker2MarkerDlg</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>262</x>
+     <y>90</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>174</x>
+     <y>54</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>Marker2MarkerDlg</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>262</x>
+     <y>90</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>174</x>
+     <y>54</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
Index: scribus/ui/marker2item.h
===================================================================
--- scribus/ui/marker2item.h	(wersja 0)
+++ scribus/ui/marker2item.h	(wersja 0)
@@ -0,0 +1,20 @@
+#ifndef MARKER2ITEM_H
+#define MARKER2ITEM_H
+
+#include "markerinsertdlgbase.h"
+#include "ui_marker2item.h"
+
+class SCRIBUS_API Marker2ItemDlg : public MarkerInsertDlg, private Ui::Marker2ItemDlg
+{
+    Q_OBJECT
+
+public:
+	explicit Marker2ItemDlg(QWidget *parent = 0);
+	virtual void values(QString &label, PageItem* &ptr);
+	virtual void setValues(const QString label, const PageItem* ptr);
+
+protected:
+	void changeEvent(QEvent *e);
+};
+
+#endif // MARKER2ITEM_H
Index: scribus/ui/markerinsertdlgbase.h
===================================================================
--- scribus/ui/markerinsertdlgbase.h	(wersja 0)
+++ scribus/ui/markerinsertdlgbase.h	(wersja 0)
@@ -0,0 +1,39 @@
+#ifndef MARKERINSERTDLG_H
+#define MARKERINSERTDLG_H
+
+#include <QDialog>
+#include <scribusapi.h>
+
+class NotesSet;
+class Marker;
+class PageItem;
+
+class SCRIBUS_API MarkerInsertDlg : public QDialog
+{
+	Q_OBJECT
+
+public:
+	MarkerInsertDlg(const QVector<Marker*>&, QWidget *parent = 0) : QDialog(parent) {}
+	MarkerInsertDlg(const QList<NotesSet*>&, QWidget *parent = 0) : QDialog(parent) {}
+	MarkerInsertDlg(QWidget *parent = 0) : QDialog(parent) {}
+	~MarkerInsertDlg() {}
+
+	virtual void values(QString &label) {}
+	virtual void values(QString &label, PageItem* &item) {}
+	virtual Marker* values(QString& label, QString& text) { return NULL; }
+	virtual void values(QString& label, Marker* &marker) {}
+	virtual NotesSet* values() { return NULL; }
+
+	virtual void setValues(const QString label) {}
+	virtual void setValues(const QString label, const QString text) {}
+	virtual void setValues(const QString label, const PageItem* ptr) {}
+	virtual void setValues(const QString label, const Marker* ptr) {}
+	virtual void setValues(const NotesSet* defaultSet) {}
+	
+signals:
+
+public slots:
+
+};
+
+#endif // MARKERINSERTDLG_H
Index: scribus/ui/markersmanager.h
===================================================================
--- scribus/ui/markersmanager.h	(wersja 0)
+++ scribus/ui/markersmanager.h	(wersja 0)
@@ -0,0 +1,42 @@
+#ifndef MARKERSMANAGER_H
+#define MARKERSMANAGER_H
+
+#include "ui/scrpalettebase.h"
+#include "ui_markersmanager.h"
+#include "markers.h"
+class QEvent;
+class  ScribusDoc;
+
+class SCRIBUS_API MarkersManager : public ScrPaletteBase, Ui::MarkersManager
+{
+	Q_OBJECT
+
+public:
+	explicit MarkersManager(QWidget *parent = 0, const char *name = "MarkersManager");
+	~MarkersManager();
+	void updateListView();
+private:
+	ScribusDoc         *m_doc;
+	PrefsContext       *m_prefs;
+	Marker* getMarkerFromListView();
+	void addListItem(MarkerType typeMrk, QString typeStr, QVector<Marker*> &markers, int &index);
+
+protected:
+	void changeEvent(QEvent *e);
+	void hideEvent(QHideEvent *e);
+	void closeEvent(QCloseEvent *e);
+	void showEvent(QShowEvent *e);
+
+public slots:
+	void setDoc(ScribusDoc *doc);
+	void languageChange();
+
+private slots:
+	void on_UpdateButton_clicked();
+	void on_EditButton_clicked();
+	void on_DeleteButton_clicked();
+	void on_listView_doubleClicked(const QModelIndex &index);
+	void on_listView_itemSelectionChanged();
+};
+
+#endif // MARKERSMANAGER_H
Index: scribus/ui/marker2marker.h
===================================================================
--- scribus/ui/marker2marker.h	(wersja 0)
+++ scribus/ui/marker2marker.h	(wersja 0)
@@ -0,0 +1,20 @@
+#ifndef MARKER2MARKER_H
+#define MARKER2MARKER_H
+
+#include "markerinsertdlgbase.h"
+#include "ui_marker2marker.h"
+
+class SCRIBUS_API Marker2MarkerDlg : public MarkerInsertDlg, private Ui::Marker2MarkerDlg
+{
+    Q_OBJECT
+
+public:
+	explicit Marker2MarkerDlg(const QVector<Marker*>& markers, Marker* omitMarker = NULL, QWidget *parent = NULL);
+	virtual void values(QString& label, Marker* &marker);
+	virtual void setValues(const QString label, const Marker* marker);
+
+protected:
+    void changeEvent(QEvent *e);
+};
+
+#endif // MARKER2MARKER_H
Index: scribus/ui/markeranchor.cpp
===================================================================
--- scribus/ui/markeranchor.cpp	(wersja 0)
+++ scribus/ui/markeranchor.cpp	(wersja 0)
@@ -0,0 +1,30 @@
+#include "markeranchor.h"
+
+MarkerAnchorDlg::MarkerAnchorDlg(QWidget *parent) :
+	MarkerInsertDlg(parent)
+{
+	setupUi(this);
+	setWindowTitle(tr("Anchor Marker"));
+}
+
+void MarkerAnchorDlg:: values(QString& label)
+{
+	label = labelEdit->text();
+}
+
+void MarkerAnchorDlg::setValues(const QString label)
+{
+	labelEdit->setText(label);
+}
+
+void MarkerAnchorDlg::changeEvent(QEvent *e)
+{
+	QDialog::changeEvent(e);
+	switch (e->type()) {
+		case QEvent::LanguageChange:
+			retranslateUi(this);
+			break;
+		default:
+			break;
+	}
+}
Index: scribus/ui/markervariabletext.cpp
===================================================================
--- scribus/ui/markervariabletext.cpp	(wersja 0)
+++ scribus/ui/markervariabletext.cpp	(wersja 0)
@@ -0,0 +1,87 @@
+#include "markervariabletext.h"
+#include "markers.h"
+#include <QComboBox>
+
+MarkerVariableTextDlg::MarkerVariableTextDlg(const QVector<Marker*>& markers,bool listEnabled, QWidget *parent) : MarkerInsertDlg(markers, parent)
+{
+	setupUi(this);
+
+	//if listEnabled in dialog is inserted QComboBox with list of markers, otherwise is inserted QLineEdit
+	if (listEnabled)
+	{
+		labelEditWidget = (QWidget*) new QComboBox(parent);
+		((QComboBox*) labelEditWidget)->addItem("New Marker", QVariant::fromValue((void*) NULL));
+		for (int i = 0; i < markers.size(); ++i)
+		{
+			if (markers[i]->getType() == MARKERVariableTextType)
+				((QComboBox*) labelEditWidget)->addItem(markers[i]->label, QVariant::fromValue((void*) markers[i]));
+		}
+		((QComboBox*) labelEditWidget)->setEditable(true);
+		((QComboBox*) labelEditWidget)->lineEdit()->setToolTip(tr("Edit selected Marker label. To create new Marker select \"New Marker\" in drop list and input new label"));
+		connect(((QComboBox*) labelEditWidget), SIGNAL(currentIndexChanged(int)),this,SLOT(on_LabelList_currentIndexChanged(int)));
+	}
+	else
+	{
+		labelEditWidget = (QWidget*) new QLineEdit(parent);
+		((QLineEdit*) labelEditWidget)->setToolTip(tr("Edit selected Marker label."));
+	}
+	labelLayout->addWidget(labelEditWidget);
+	textEdit->setToolTip(tr("Edit variable text"));
+	setWindowTitle(tr("Marker with Variable Text"));
+}
+
+MarkerVariableTextDlg::~MarkerVariableTextDlg()
+{
+	//delete ui;
+	delete labelEditWidget;
+}
+
+Marker* MarkerVariableTextDlg::values(QString& label, QString& text)
+{
+	text = textEdit->text();
+	//hack to read if it is QComboBox or QLineEdit
+	if (labelEditWidget->toolTip() != tr("Edit selected Marker label."))
+	{
+		int labelID = ((QComboBox*) labelEditWidget)->currentIndex();
+		label = ((QComboBox*) labelEditWidget)->currentText();
+		return (Marker*) ((QComboBox*) labelEditWidget)->itemData(labelID).value<void*>();
+	}
+	else
+		label = ((QLineEdit*) labelEditWidget)->text();
+	return NULL;
+}
+
+void MarkerVariableTextDlg::setValues(QString label, QString text)
+{
+	if (labelEditWidget->toolTip() == tr("Edit selected Marker label."))
+		((QLineEdit*) labelEditWidget)->setText(label);
+	else
+		((QComboBox*) labelEditWidget)->setCurrentIndex(((QComboBox*) labelEditWidget)->findText(label));
+	textEdit->setText(text);
+}
+
+void MarkerVariableTextDlg::changeEvent(QEvent *e)
+{
+	QDialog::changeEvent(e);
+	switch (e->type()) {
+		case QEvent::LanguageChange:
+			retranslateUi(this);
+			break;
+		default:
+			break;
+	}
+}
+
+void MarkerVariableTextDlg::on_LabelList_currentIndexChanged(int index)
+{
+	if (index > 0)
+	{
+		Marker* marker = (Marker*) ((QComboBox*) labelEditWidget)->itemData(index).value<void*>();
+		textEdit->setText(marker->getString());
+	}
+	else
+	{
+		((QComboBox*) labelEditWidget)->setEditText("");
+		textEdit->clear();
+	}
+}
Index: scribus/ui/markervariabletext.ui
===================================================================
--- scribus/ui/markervariabletext.ui	(wersja 0)
+++ scribus/ui/markervariabletext.ui	(wersja 0)
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MarkerVariableTextDlg</class>
+ <widget class="QDialog" name="MarkerVariableTextDlg">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>394</width>
+    <height>117</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>0</width>
+    <height>117</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>117</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Add new Marker for Variable Text</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QHBoxLayout" name="labelLayout">
+     <item>
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Label:</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Text to insert:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="textEdit"/>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>202</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="buttonBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>MarkerVariableTextDlg</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>MarkerVariableTextDlg</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
Index: scribus/ui/marker2marker.cpp
===================================================================
--- scribus/ui/marker2marker.cpp	(wersja 0)
+++ scribus/ui/marker2marker.cpp	(wersja 0)
@@ -0,0 +1,111 @@
+#include "markers.h"
+#include "marker2marker.h"
+#include <QStandardItemModel>
+
+Marker2MarkerDlg::Marker2MarkerDlg(const QVector<Marker*>& markers, Marker* omitMarker, QWidget *parent) : MarkerInsertDlg(markers, parent)
+{
+	setupUi(this);
+	LabelList->addItem("", QVariant::fromValue((void*) NULL));
+	
+	//for each marker`s type
+	QString typeStr;
+	MarkerType typeMrk;
+
+	int index = 0;
+	typeMrk = MARKERAnchorType;	typeStr = tr("Anchors");
+	//adding name of markers type, and make it unselectable
+	LabelList->addItem("+++ " + typeStr);
+	qobject_cast<QStandardItemModel *>(LabelList->model())->item( ++index )->setEnabled( false );
+	for (int i = 0; i < markers.size(); ++i)
+	{
+		if (markers[i]->getType() == typeMrk)
+		{
+			LabelList->addItem(markers[i]->label, QVariant::fromValue((void*) markers[i]));
+			index++;
+		}
+	}
+	typeMrk = MARKER2MarkerType;	typeStr = tr("Marker to Marker");
+	LabelList->addItem("+++ " + typeStr);
+	qobject_cast<QStandardItemModel *>(LabelList->model())->item( ++index )->setEnabled( false );
+	for (int i = 0; i < markers.size(); ++i)
+	{
+		if (markers[i]->getType() == typeMrk && markers[i] != omitMarker)
+		{
+			LabelList->addItem(markers[i]->label, QVariant::fromValue((void*) markers[i]));
+			index++;
+		}
+	}
+	typeMrk = MARKER2ItemType;	typeStr = tr("Marker to Item");
+	LabelList->addItem("+++ " + typeStr);
+	qobject_cast<QStandardItemModel *>(LabelList->model())->item( ++index )->setEnabled( false );
+	for (int i = 0; i < markers.size(); ++i)
+	{
+		if (markers[i]->getType() == typeMrk)
+		{
+			LabelList->addItem(markers[i]->label, QVariant::fromValue((void*) markers[i]));
+			index++;
+		}
+	}
+//	typeMrk = MARKERFootnoteType;	typeStr = tr("Footnote marker");
+//	LabelList->addItem("+++ " + typeStr);
+//	qobject_cast<QStandardItemModel *>(LabelList->model())->item( ++index )->setEnabled( false );
+//	for (int i = 0; i < markers.size(); ++i)
+//	{
+//		if (markers[i]->getType() == typeMrk)
+//		{
+//			LabelList->addItem(markers[i]->label, QVariant::fromValue((void*) markers[i]));
+//			index++;
+//		}
+//	}
+//	typeMrk = MARKEREndnoteType;	typeStr = tr("Endnote marker");
+//	LabelList->addItem("+++ " + typeStr);
+//	qobject_cast<QStandardItemModel *>(LabelList->model())->item( ++index )->setEnabled( false );
+//	for (int i = 0; i < markers.size(); ++i)
+//	{
+//		if (markers[i]->getType() == typeMrk)
+//		{
+//			LabelList->addItem(markers[i]->label, QVariant::fromValue((void*) markers[i]));
+//			index++;
+//		}
+//	}
+//	typeMrk = MARKERIndexType;	typeStr = tr("Index entry");
+//	LabelList->addItem("+++ " + typeStr);
+//	qobject_cast<QStandardItemModel *>(LabelList->model())->item( ++index )->setEnabled( false );
+//	for (int i = 0; i < markers.size(); ++i)
+//	{
+//		if (markers[i]->getType() == typeMrk)
+//		{
+//			LabelList->addItem(markers[i]->label, QVariant::fromValue((void*) markers[i]));
+//			index++;
+//		}
+//	}
+	setWindowTitle(tr("Marker to Marker"));
+}
+
+void Marker2MarkerDlg::values(QString& label, Marker* &marker)
+{
+	label = this->labelEdit->text();
+	int labelID = LabelList->currentIndex();
+	if (labelID == 0)
+		marker= NULL;
+	else
+		marker = (Marker*) LabelList->itemData(labelID).value<void*>();
+}
+
+void Marker2MarkerDlg::setValues(const QString label, const Marker* marker)
+{
+	LabelList->setCurrentIndex(LabelList->findText(marker->label));
+	labelEdit->setText(label);
+}
+
+void Marker2MarkerDlg::changeEvent(QEvent *e)
+{
+    QDialog::changeEvent(e);
+    switch (e->type()) {
+    case QEvent::LanguageChange:
+        retranslateUi(this);
+        break;
+    default:
+        break;
+    }
+}
Index: scribus/ui/marker2item.ui
===================================================================
--- scribus/ui/marker2item.ui	(wersja 0)
+++ scribus/ui/marker2item.ui	(wersja 0)
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Marker2ItemDlg</class>
+ <widget class="QDialog" name="Marker2ItemDlg">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>349</width>
+    <height>102</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>115</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <layout class="QFormLayout" name="formLayout">
+     <property name="fieldGrowthPolicy">
+      <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+     </property>
+     <item row="0" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Label:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QLineEdit" name="labelEdit"/>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Item:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QComboBox" name="ItemList">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="editable">
+        <bool>false</bool>
+       </property>
+       <property name="currentIndex">
+        <number>-1</number>
+       </property>
+       <property name="duplicatesEnabled">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="1" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>164</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="buttonBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>Marker2ItemDlg</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>262</x>
+     <y>90</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>174</x>
+     <y>54</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>Marker2ItemDlg</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>262</x>
+     <y>90</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>174</x>
+     <y>54</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
Index: scribus/ui/markeranchor.h
===================================================================
--- scribus/ui/markeranchor.h	(wersja 0)
+++ scribus/ui/markeranchor.h	(wersja 0)
@@ -0,0 +1,20 @@
+#ifndef MARKERANCHOR_H
+#define MARKERANCHOR_H
+
+#include "markerinsertdlgbase.h"
+#include "ui_markeranchor.h"
+
+class SCRIBUS_API MarkerAnchorDlg : public MarkerInsertDlg, private Ui::MarkerAnchorDlg
+{
+    Q_OBJECT
+
+public:
+	explicit MarkerAnchorDlg(QWidget *parent = 0);
+	~MarkerAnchorDlg() {}
+	virtual void values(QString& label);
+	virtual void setValues(const QString label);
+protected:
+	void changeEvent(QEvent *e);
+};
+
+#endif // MARKERANCHOR_H
Index: scribus/ui/markervariabletext.h
===================================================================
--- scribus/ui/markervariabletext.h	(wersja 0)
+++ scribus/ui/markervariabletext.h	(wersja 0)
@@ -0,0 +1,24 @@
+#ifndef MARKERVARIABLETEXT_H
+#define MARKERVARIABLETEXT_H
+
+#include "scribusapi.h"
+#include "markerinsertdlgbase.h"
+#include "ui_markervariabletext.h"
+
+class SCRIBUS_API MarkerVariableTextDlg : public MarkerInsertDlg, private Ui::MarkerVariableTextDlg
+{
+	Q_OBJECT
+public:
+	explicit MarkerVariableTextDlg(const QVector<Marker*>&, bool listEnabled, QWidget *parent = 0);
+	~MarkerVariableTextDlg();
+	virtual Marker* values(QString& label, QString& text);
+	virtual void setValues(const QString label, const QString text);
+protected:
+	void changeEvent(QEvent *e);
+private slots:
+	void on_LabelList_currentIndexChanged(int index);
+private:
+	QWidget* labelEditWidget;
+};
+
+#endif // MARKERVARIABLETEXT_H
Index: scribus/ui/markeranchor.ui
===================================================================
--- scribus/ui/markeranchor.ui	(wersja 0)
+++ scribus/ui/markeranchor.ui	(wersja 0)
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MarkerAnchorDlg</class>
+ <widget class="QDialog" name="MarkerAnchorDlg">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>81</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>0</width>
+    <height>81</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>81</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Label:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1">
+    <widget class="QLineEdit" name="labelEdit"/>
+   </item>
+   <item row="1" column="1">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>MarkerAnchorDlg</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>MarkerAnchorDlg</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
Index: scribus/ui/contextmenu.cpp
===================================================================
--- scribus/ui/contextmenu.cpp	(wersja 17188)
+++ scribus/ui/contextmenu.cpp	(kopia robocza)
@@ -94,6 +94,7 @@
 	QMenu *menuLayer = new QMenu(this);
 	QMenu *menuLevel = new QMenu(this);
 	QMenu *menuPDF = new QMenu(this);
+	QMenu *menuMarker = new QMenu(this);
 	QMenu *menuResolution = new QMenu(this);
 //	QMenu *menuWeld = new QMenu(this);
 	
@@ -172,6 +173,25 @@
 			addAction(m_AP->scrActions["fileImportAppendText"]);
 			addAction(m_AP->scrActions["toolsEditWithStoryEditor"]);
 			addAction(m_AP->scrActions["insertSampleText"]);
+			if (m_doc->appMode == modeEdit)
+			{
+				QAction *act2 = addMenu(menuMarker);
+				act2->setText( ScribusView::tr("Insert Marker"));
+				menuMarker->addAction(m_AP->scrActions["insertMarkerAnchor"]);
+				menuMarker->addAction(m_AP->scrActions["insertMarkerVariableText"]);
+				menuMarker->addAction(m_AP->scrActions["insertMarkerItem"]);
+				menuMarker->addAction(m_AP->scrActions["insertMarker2Marker"]);
+//				menuMarker->addAction(m_AP->scrActions["insertMarkerFootnote"]);
+//				menuMarker->addAction(m_AP->scrActions["insertMarkerEndnote"]);
+//				menuMarker->addAction(m_AP->scrActions["insertMarkerIndex"]);
+				if (currItem->itemText.cursorPosition() < currItem->itemText.length())
+				{
+					ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+					if (hl->ch == SpecialChars::OBJECT && hl->marker != NULL)
+						addAction(m_AP->scrActions["editMarker"]);
+				}
+
+			}
 		}
 		else //enable this for, eg, text on a path
 			if (m_actionList.contains("toolsEditWithStoryEditor"))
Index: scribus/text/storytext.cpp
===================================================================
--- scribus/text/storytext.cpp	(wersja 17188)
+++ scribus/text/storytext.cpp	(kopia robocza)
@@ -329,10 +329,13 @@
 		if ((it->ch == SpecialChars::PARSEP)) {
 			removeParSep(i);
 		}
+		Marker* mrk = it->marker;
 //		qDebug("remove char %d at %d", (int) it->ch.unicode(), i);
 		d->takeAt(i);
 		d->len--;
 		delete it;
+		if ((mrk != NULL) && mrk->isUnique())
+			doc->eraseMarker(mrk);
 		// #9592 : adjust selFirst and selLast, those values have to be
 		// consistent in functions such as select()
 		if (i <= selLast) --selLast;
@@ -477,6 +480,15 @@
 	invalidate(pos, pos + 1);
 }
 
+void StoryText::insertMarker(Marker* M, int pos)
+{
+	if (pos < 0)
+		pos = d->cursorPosition;
+
+	insertChars(pos, SpecialChars::OBJECT);
+	const_cast<StoryText *>(this)->d->at(pos)->marker = M;
+}
+
 void StoryText::hyphenateWord(int pos, uint len, char* hyphens)
 {
 	assert(pos >= 0);
Index: scribus/text/storytext.h
===================================================================
--- scribus/text/storytext.h	(wersja 17188)
+++ scribus/text/storytext.h	(kopia robocza)
@@ -126,6 +126,8 @@
 	// Insert object at specific position
  	void insertObject(int pos, PageItem* obj);
  	void replaceChar(int pos, QChar ch);
+	// Insert marker at cursor or specific position
+	void insertMarker(Marker* M, int pos = -1);
 
 	void hyphenateWord(int pos, uint len, char* hyphens);
 	
Index: scribus/markers.h
===================================================================
--- scribus/markers.h	(wersja 0)
+++ scribus/markers.h	(wersja 0)
@@ -0,0 +1,77 @@
+#ifndef MARKERS_H
+#define MARKERS_H
+
+#include <QString>
+#include "scribusapi.h"
+class Marker;
+class PageItem;
+
+enum MarkerType
+{
+	MARKERNoType = -1, //undefinied marker type (wrong situation!)
+	MARKERAnchorType = 0, //empty anchor marker, useful for creating references to it
+	MARKER2ItemType = 1, //reference to page item ID
+	MARKER2MarkerType = 2, //reference other marker
+	MARKERVariableTextType = 3,//marker contain dynamic text
+	MARKERFootnoteType = 4,  //marker contain footnote
+	MARKEREndnoteType = 5,  //marker contain endnote
+	MARKERIndexType = 6 // index entry
+};
+
+struct MarkerData
+{
+	PageItem* itemPtr;
+	QString* strPtr;
+	Marker* mrkPtr;
+	QString itemName;
+};
+
+class SCRIBUS_API Marker
+{
+public:
+	QString label;
+	int OwnPage;
+	Marker() { label = "", OwnPage = -1, typ = MARKERNoType, data.itemPtr = NULL; data.strPtr = NULL; data.mrkPtr = NULL; }
+	Marker(const Marker& other) : label(other.label), OwnPage(other.OwnPage), typ(other.typ), data(other.data) {}
+	~Marker()
+	{
+		if (data.strPtr != NULL)
+			delete data.strPtr;
+	}
+	void setValues(QString l, int p, MarkerType t, MarkerData d) { label = l; OwnPage = p; typ = t; data = d; }
+	MarkerType getType() { return typ; }
+	void setType(MarkerType t) { typ = t; }
+	MarkerData getData() { return data; }
+	void setData(MarkerData d) { data = d; }
+	PageItem* getItemPtr() { return data.itemPtr; }
+	void setItemPtr( PageItem* ptr ) { data.itemPtr = ptr; }
+	QString getItemName() { return data.itemName; }
+	void setItemName( QString name ) { data.itemName = name; }
+	QString* getStrPtr() { return data.strPtr; }
+	QString getString()
+	{
+		if (data.strPtr != NULL)
+			return *data.strPtr;
+		else
+			return "";
+	}
+	void setMarker(Marker* mP) { data.mrkPtr = mP; }
+	Marker* getMarker() { return data.mrkPtr; }
+	void setStrPtr( QString* p ) { data.strPtr = p; }
+	void setString( QString str )
+	{
+		if (data.strPtr != NULL)
+			delete data.strPtr;
+		data.strPtr = new QString(str);
+	}
+
+	bool hasItemPtr() { return data.itemPtr != NULL; }
+	bool hasString() { return getString() != ""; }
+	bool hasMarker() { return data.mrkPtr != NULL; }
+	bool isUnique() { return (typ==MARKERAnchorType || typ==MARKERFootnoteType || typ==MARKEREndnoteType); }
+private:
+	MarkerType typ;
+	MarkerData data;
+};
+
+#endif // MARKERS_H
Index: scribus/scribus.cpp
===================================================================
--- scribus/scribus.cpp	(wersja 17188)
+++ scribus/scribus.cpp	(kopia robocza)
@@ -99,6 +99,7 @@
 #include "gtgettext.h"
 #include "hyphenator.h"
 #include "langmgr.h"
+#include "markers.h"
 #include "pageitem_group.h"
 #include "pageitem_imageframe.h"
 #include "pageitem_latexframe.h"
@@ -163,6 +164,8 @@
 #include "ui/loremipsum.h"
 #include "ui/marginwidget.h"
 #include "ui/margindialog.h"
+#include "ui/markerinsertdlgbase.h"
+#include "ui/markersmanager.h"
 #include "ui/masterpagepalette.h"
 #include "ui/mergedoc.h"
 #include "ui/movepage.h"
@@ -582,6 +585,12 @@
 	connect( styleManager, SIGNAL(paletteShown(bool)), scrActions["editStyles"], SLOT(setChecked(bool)));
 	styleManager->installEventFilter(this);
 
+	// initializing marker`s manager
+	markersManager = new MarkersManager(this, "markersManager");
+	connect( scrActions["editMarkers"], SIGNAL(toggled(bool)), markersManager, SLOT(setPaletteShown(bool)) );
+	connect( markersManager, SIGNAL(paletteShown(bool)), scrActions["editMarkers"], SLOT(setChecked(bool)));
+	markersManager->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)));
@@ -721,6 +730,7 @@
 //	scrMenuMgr->addMenuItem(scrActions["editGradients"], "Edit", false);
 //	scrMenuMgr->addMenuItem(scrActions["editPatterns"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editStyles"], "Edit", false);
+	scrMenuMgr->addMenuItem(scrActions["editMarkers"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editMasterPages"], "Edit", false);
 	scrMenuMgr->addMenuItem(scrActions["editJavascripts"], "Edit", false);
 	scrMenuMgr->setMenuEnabled("EditPasteRecent", false);
@@ -837,6 +847,8 @@
 	scrMenuMgr->addMenuItem(scrActions["itemWeld"], "Item", false);
 	scrMenuMgr->addMenuItem(scrActions["itemEditWeld"], "Item", false);
 
+	scrMenuMgr->addMenuItem(scrActions["editMarker"], "Item", false);
+
 	//Insert menu
 	scrMenuMgr->createMenu("Insert", ActionManager::defaultMenuNameEntryTranslated("Insert"));
 	scrMenuMgr->addMenuItem(scrActions["insertFrame"], "Insert", false);
@@ -927,6 +939,15 @@
 
 	scrMenuMgr->addMenuSeparator("Insert");
 	scrMenuMgr->addMenuItem(scrActions["insertSampleText"], "Insert", false);
+	scrMenuMgr->addMenuSeparator("Insert");
+	scrMenuMgr->createMenu("InsertMarker", tr("Markers"), "Insert");
+	scrMenuMgr->addMenuItem(scrActions["insertMarkerAnchor"], "InsertMarker", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarkerVariableText"], "InsertMarker", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarkerItem"], "InsertMarker", false);
+	scrMenuMgr->addMenuItem(scrActions["insertMarker2Marker"], "InsertMarker", false);
+//	scrMenuMgr->addMenuItem(scrActions["insertMarkerFootnote"], "InsertMarker", false);
+//	scrMenuMgr->addMenuItem(scrActions["insertMarkerEndnote"], "InsertMarker", false);
+//	scrMenuMgr->addMenuItem(scrActions["insertMarkerIndex"], "InsertMarker", false);
 
 	//Page menu
 	scrMenuMgr->createMenu("Page", ActionManager::defaultMenuNameEntryTranslated("Page"));
@@ -1129,6 +1150,7 @@
 //AV to be replaced with Selection::update and listener in PropertiesPalette
 void ScribusMainWindow::setTBvals(PageItem *currItem)
 {
+	scrActions["editMarker"]->setEnabled(false);
 	if (currItem->itemText.length() != 0)
 	{
 //		int ChPos = qMin(currItem->CPos, static_cast<int>(currItem->itemText.length()-1));
@@ -1142,6 +1164,11 @@
 		emit TextStyle(doc->currentStyle);
 		// to go: (av)
 		propertiesPalette->textPal->updateStyle(doc->currentStyle);
+		if (doc->appMode == modeEdit && currItem->itemText.cursorPosition() < currItem->itemText.length())
+		{
+			ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+			scrActions["editMarker"]->setEnabled((hl->ch == SpecialChars::OBJECT && hl->marker != NULL));
+		}
 	}
 }
 
@@ -1984,6 +2011,7 @@
 		tempView->cmsToolbarButton->setChecked(tempDoc->HasCMS);
 		undoManager->switchStack(tempDoc->DocName);
 		styleManager->setDoc(tempDoc);
+		markersManager->setDoc(tempDoc);
 		tocGenerator->setDoc(tempDoc);
 	}
 	undoManager->setUndoEnabled(true);
@@ -2227,6 +2255,7 @@
 	docCheckerPalette->setDoc(doc);
 	tocGenerator->setDoc(doc);
 	styleManager->setDoc(doc);
+	markersManager->setDoc(doc);
 	symbolPalette->setDoc(doc);
 	modeToolBar->Angle->setValue(doc->itemToolPrefs().calligrapicPenAngle);
 	modeToolBar->PWidth->setValue(doc->itemToolPrefs().calligrapicPenWidth);
@@ -2258,6 +2287,7 @@
 	updateActiveWindowCaption(doc->DocName);
 // 	scrActions["shade100"]->setChecked(true);
 	propertiesPalette->setDoc(doc);
+	markersManager->setDoc(doc);
 	//propertiesPalette->Cpal->displayGradient(0);
 	pagePalette->setView(view);
 	layerPalette->setDoc(doc);
@@ -2397,6 +2427,7 @@
 //	scrActions["editPatterns"]->setEnabled(true);
 //	scrActions["editGradients"]->setEnabled(true);
  	scrActions["editStyles"]->setEnabled(true);
+	scrActions["editMarkers"]->setEnabled(true);
 	scrActions["editMasterPages"]->setEnabled(true);
 	scrActions["editJavascripts"]->setEnabled(true);
 
@@ -2463,6 +2494,7 @@
 	updateActiveWindowCaption(doc->DocName);
 // 	scrActions["shade100"]->setChecked(true);
 	propertiesPalette->setDoc(doc);
+	markersManager->setDoc(doc);
 	symbolPalette->setDoc(doc);
 //	propertiesPalette->Cpal->displayGradient(0);
 //	propertiesPalette->updateColorList();
@@ -2816,6 +2848,16 @@
 		scrActions["toolsCopyProperties"]->setEnabled(true);
 		scrActions["toolsEditWithStoryEditor"]->setEnabled(true);
 		scrActions["insertSampleText"]->setEnabled(true);
+		scrMenuMgr->setMenuEnabled("InsertMarker",true);
+		scrActions["insertMarkerAnchor"]->setEnabled(true);
+		scrActions["insertMarkerVariableText"]->setEnabled(true);
+		scrActions["insertMarkerItem"]->setEnabled(true);
+		scrActions["insertMarker2Marker"]->setEnabled(true);
+//		scrActions["insertMarkerFootnote"]->setEnabled(true);
+//		scrActions["insertMarkerEndnote"]->setEnabled(true);
+//		scrActions["insertMarkerIndex"]->setEnabled(true);
+		scrActions["editMarker"]->setEnabled(false);
+
 		if ((currItem->nextInChain() != 0) || (currItem->prevInChain() != 0))
 		{
 			scrActions["itemConvertToBezierCurve"]->setEnabled(false);
@@ -2844,6 +2886,8 @@
 			setTBvals(currItem);
 			scrActions["editSelectAll"]->setEnabled(true);
 			scrActions["editSelectAllOnLayer"]->setEnabled(false);
+			scrActions["insertSampleText"]->setEnabled(true);
+			scrMenuMgr->setMenuEnabled("InsertMarker",true);
 			charPalette->setEnabled(true, currItem);
 			if (currItem->asTextFrame())
 				enableTextActions(&scrActions, true, currItem->currentStyle().charStyle().font().scName());
@@ -2852,6 +2896,7 @@
 		}
 		else
 		{
+			scrMenuMgr->setMenuEnabled("InsertMarker",false);
 			doc->currentStyle = currItem->itemText.defaultStyle();
 			propertiesPalette->textPal->displayParStyle(doc->currentStyle.parent());
 			propertiesPalette->textPal->displayCharStyle(doc->currentStyle.charStyle().parent());
@@ -3204,6 +3249,7 @@
 //		scanDocument();
 //		docCheckerPalette->buildErrorList(doc);
 //	}
+//	doc->updateMarkers();
 	if (!doc->isModified())
 		doc->setModified(true);
 	updateActiveWindowCaption(doc->DocName + "*");
@@ -4185,6 +4231,7 @@
 			view->DrawNew();
 			slotDocCh();
 			styleManager->setDoc(doc);
+			markersManager->setDoc(doc);
 		}
 	}
 }
@@ -4585,6 +4632,7 @@
 //		scrActions["editPatterns"]->setEnabled(false);
 //		scrActions["editGradients"]->setEnabled(false);
 		scrActions["editStyles"]->setEnabled(false);
+		scrActions["editMarkers"]->setEnabled(false);
 		scrActions["editSearchReplace"]->setEnabled(false);
 		scrActions["editMasterPages"]->setEnabled(false);
 		scrActions["editJavascripts"]->setEnabled(false);
@@ -4690,6 +4738,7 @@
 	charPalette->setDoc(0);
 	tocGenerator->setDoc(0);
 	styleManager->setDoc(0);
+	markersManager->setDoc(0);
 	layerPalette->ClearInhalt();
 	docCheckerPalette->buildErrorList(0);
 	HaveDoc--;
@@ -5073,6 +5122,7 @@
 				styleManager->setDoc(doc);
 				propertiesPalette->unsetDoc();
 				propertiesPalette->setDoc(doc);
+				markersManager->setDoc(doc);
 				symbolPalette->unsetDoc();
 				symbolPalette->setDoc(doc);
 
@@ -5154,6 +5204,7 @@
 				styleManager->setDoc(doc);
 				propertiesPalette->unsetDoc();
 				propertiesPalette->setDoc(doc);
+				markersManager->setDoc(doc);
 				symbolPalette->unsetDoc();
 				symbolPalette->setDoc(doc);
 
@@ -6429,8 +6480,8 @@
 //					view->requestMode(modeEditClip);
 //					return;
 //				}
+				currItem->itemText.setCursorPosition(0);
 				setTBvals(currItem);
-				currItem->itemText.setCursorPosition(0);
 			}
 			scrActions["editPaste"]->setEnabled(false);
 			charPalette->setEnabled(true, currItem);
@@ -7771,6 +7822,7 @@
 	guidePalette->startup();
 	charPalette->startup();
 	styleManager->startup();
+	markersManager->startup();
 	symbolPalette->startup();
 
 	// init the toolbars
@@ -10050,6 +10102,7 @@
 	scrMenuMgr->setMenuEnabled("InsertQuote", enabled);
 	scrMenuMgr->setMenuEnabled("InsertSpace", enabled);
 	scrMenuMgr->setMenuEnabled("InsertLigature", enabled);
+	scrMenuMgr->setMenuEnabled("InsertMarker", enabled);
 }
 
 void ScribusMainWindow::updateTableMenuActions()
@@ -10081,4 +10134,76 @@
 	scrActions["tableAdjustFrameToTable"]->setEnabled(table);
 	scrActions["tableAdjustTableToFrame"]->setEnabled(table);
 }
+void ScribusMainWindow::insertMarker(MarkerType mType)
+{
+	if (HaveDoc && doc->m_Selection->itemAt(0)->isTextFrame() && doc->appMode == modeEdit)
+	{
+		doc->m_Selection->itemAt(0)->asTextFrame()->insertMarkerDlg(mType);
+		update();
+	}
+}
 
+void ScribusMainWindow::slotEditMarker()
+{
+	if (HaveDoc && doc->m_Selection->itemAt(0)->isTextFrame() && doc->appMode == modeEdit)
+	{
+		PageItem * currItem = doc->m_Selection->itemAt(0);
+		if (currItem->itemText.cursorPosition() < currItem->itemText.length())
+		{
+			ScText *hl = currItem->itemText.item(currItem->itemText.cursorPosition());
+			if (hl->ch == SpecialChars::OBJECT && hl->marker != NULL)
+			{
+				currItem->asTextFrame()->editMarkerDlg(hl->marker);
+				slotUpdateMarkers();
+			}
+		}
+	}
+}
+
+void ScribusMainWindow::slotUpdateMarkers()
+{
+	QMap<QString,Marker*>::Iterator markIt;
+	for(markIt = doc->markersMap.begin(); markIt != doc->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		int itemIndex = -1;
+		PageItem* item = doc->findMarker(marker, itemIndex);
+		while (item != NULL)
+		{
+			QString iName = item->getUName();
+			int cpos = -1;
+			if (doc->findMarkerCPos(marker, item, cpos))
+			{
+				ScText *hl = item->itemText.item(cpos);
+				if (hl->ch != SpecialChars::OBJECT || hl->marker == NULL)
+					continue;
+				if (hl->marker->getType() == marker->getType() && hl->marker->label == marker->label)
+				{
+					if (marker->getType() != MARKERVariableTextType)
+					{
+						marker->OwnPage = item->OwnPage;
+						if (marker->getType() == MARKER2ItemType)
+						{
+							PageItem* it = marker->getItemPtr();
+							if (it != NULL)
+								marker->setString(QString("%1").arg(it->OwnPage +1));
+							else
+								marker->setString("");
+						}
+						else if (marker->getType() == MARKER2MarkerType)
+						{
+							Marker* m = marker->getMarker();
+							if (m != NULL)
+								marker->setString(QString("%1").arg(m->OwnPage +1));
+							else
+								marker->setString("");
+						}
+					}
+					item->update();
+				}
+			}
+			item = doc->findMarker(marker,itemIndex);
+		}
+	}
+	doc->regionsChanged()->update(QRectF());
+}
Index: scribus/pageitem_textframe.h
===================================================================
--- scribus/pageitem_textframe.h	(wersja 17188)
+++ scribus/pageitem_textframe.h	(kopia robocza)
@@ -29,6 +29,7 @@
 
 #include "scribusapi.h"
 #include "pageitem.h"
+#include "markers.h"
 
 class ScPainter;
 class ScribusDoc;
@@ -117,6 +118,9 @@
 	
 private slots:
 	void slotInvalidateLayout();
+public:
+	void insertMarkerDlg(MarkerType mT = MARKERAnchorType);
+	void editMarkerDlg(Marker * marker);
 };
 
 #endif
Index: scribus/plugins/scriptplugin/scriptercore.cpp
===================================================================
--- scribus/plugins/scriptplugin/scriptercore.cpp	(wersja 17188)
+++ scribus/plugins/scriptplugin/scriptercore.cpp	(kopia robocza)
@@ -18,6 +18,7 @@
 
 #include "runscriptdialog.h"
 #include "ui/helpbrowser.h"
+#include "ui/markersmanager.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
@@ -151,6 +152,7 @@
 	if (ScMW->HaveDoc)
 	{
 		ScMW->propertiesPalette->setDoc(ScMW->doc);
+		ScMW->markersManager->setDoc(ScMW->doc);
 		ScMW->layerPalette->setDoc(ScMW->doc);
 		ScMW->outlinePalette->setDoc(ScMW->doc);
 		ScMW->outlinePalette->BuildTree();
Index: scribus/plugins/fileloader/scribus150format/scribus150format.h
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format.h	(wersja 17188)
+++ scribus/plugins/fileloader/scribus150format/scribus150format.h	(kopia robocza)
@@ -122,7 +122,13 @@
 		bool readPrinterOptions(ScribusDoc* doc, ScXmlStreamReader& reader);
 		bool readSections(ScribusDoc* doc, ScXmlStreamReader& reader);
 		bool readTableOfContents(ScribusDoc* doc, ScXmlStreamReader& reader);
+		bool readMarkers(ScribusDoc* doc, ScXmlStreamReader& reader);
 
+		//lists of items and markers with names only, which need update to pointers
+		QMap<QString, Marker*> markeredItemsList;
+		QMap<Marker*, QMap<QString, MarkerType> > markeredMarkersList;
+		void updateMarkersPtr(); //after document load items pointers should be updated in markeredItemList
+
 		PageItem* pasteItem(ScribusDoc *doc, ScXmlStreamAttributes& attrs, const QString& baseDir, int pagenr = -2 /* currentPage*/);
 
 		void writeCheckerProfiles(ScXmlStreamWriter& docu);
@@ -148,6 +154,7 @@
 		void writePdfOptions(ScXmlStreamWriter& docu);
 		void writeDocItemAttributes(ScXmlStreamWriter& docu);
 		void writeTOC(ScXmlStreamWriter& docu);
+		void writeMarkers(ScXmlStreamWriter & docu);
 		void writePageSets(ScXmlStreamWriter& docu);
 		void writeSections(ScXmlStreamWriter& docu);
 		void writePatterns(ScXmlStreamWriter& docu, const QString& baseDir, bool part = false, Selection* selection = 0);
Index: scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp	(wersja 17188)
+++ scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp	(kopia robocza)
@@ -389,6 +389,7 @@
 	writePdfOptions(docu);
 	writeDocItemAttributes(docu);
 	writeTOC(docu);
+	writeMarkers(docu);
 	writePageSets(docu);
 	writeSections(docu);
 	writePatterns(docu, fileDir);
@@ -1053,6 +1054,35 @@
 	docu.writeEndElement();
 }
 
+void Scribus150Format::writeMarkers(ScXmlStreamWriter & docu)
+{
+	//write list of definied markers to SLA
+	docu.writeStartElement("Markers");
+	QMap<QString,Marker*>::Iterator markIt;
+	for(markIt = m_Doc->markersMap.begin(); markIt != m_Doc->markersMap.end(); ++markIt)
+	{
+		Marker* marker = markIt.value();
+		docu.writeEmptyElement("Marker");
+		docu.writeAttribute("label", marker->label);
+		docu.writeAttribute("type", marker->getType());
+		if ((marker->getType() == MARKER2ItemType) && marker->hasItemPtr())
+		{
+			PageItem* item = marker->getItemPtr();
+			assert(item != NULL);
+			docu.writeAttribute("itemName", item->itemName());
+		}
+		else if ((marker->getType() == MARKERVariableTextType) && marker->hasString())
+			docu.writeAttribute("str", marker->getString());
+		else if ((marker->getType() == MARKER2MarkerType) && marker->hasMarker())
+		{
+			QString label = marker->getMarker()->label;
+			MarkerType type = marker->getMarker()->getType();
+			docu.writeAttribute("MARKlabel", label);
+			docu.writeAttribute("MARKtype", type);
+		}
+	}
+	docu.writeEndElement();
+}
 
 void Scribus150Format::writePageSets(ScXmlStreamWriter & docu) 
 {	
@@ -1250,6 +1280,13 @@
 			docu.writeAttribute("Unicode", tmpnum);
 			docu.writeAttribute("COBJ", qHash(item->itemText.object(k)));
 		}
+		else if (ch == SpecialChars::OBJECT && item->itemText.item(k)->marker != NULL)
+		{
+			Marker* mark = item->itemText.item(k)->marker;
+			docu.writeEmptyElement("MARKER");
+			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");
 		else if (ch == SpecialChars::TAB)
Index: scribus/plugins/fileloader/scribus150format/scribus150format.cpp
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format.cpp	(wersja 17188)
+++ scribus/plugins/fileloader/scribus150format/scribus150format.cpp	(kopia robocza)
@@ -369,6 +369,11 @@
 			success = readPattern(m_Doc, reader, fileDir);
 			if (!success) break;
 		}
+		if (tagName == "Markers")
+		{
+			success = readMarkers(m_Doc, reader);
+			if (!success) break;
+		}
 	}
 	if (reader.hasError())
 	{
@@ -829,6 +834,11 @@
 			success = readPattern(m_Doc, reader, fileDir);
 			if (!success) break;
 		}
+		if (tagName == "Markers")
+		{
+			success = readMarkers(m_Doc, reader);
+			if (!success) break;
+		}
 	}
 
 	if (reader.hasError())
@@ -1172,6 +1182,9 @@
 	WeldItems.clear();
 	WeldID.clear();
 	LinkID.clear();
+	markeredItemsList.clear();
+	markeredMarkersList.clear();
+	
 
 	m_Doc->GroupCounter = 1;
 	m_Doc->LastAuto = 0;
@@ -1433,6 +1446,11 @@
 			if (!success)
 				break;
 		}
+		if (tagName == "Markers")
+		{
+			success = readMarkers(m_Doc, reader);
+			if (!success) break;
+		}
 	}
 
 	if (reader.hasError())
@@ -1724,6 +1742,7 @@
 			gItem->groupItemList = gpL;
 		}
 	}
+	updateMarkersPtr();
 	
 	// reestablish first/lastAuto
 	m_Doc->FirstAuto = m_Doc->LastAuto;
@@ -2761,6 +2780,68 @@
 	return !reader.hasError();
 }
 
+bool Scribus150Format::readMarkers(ScribusDoc* doc, ScXmlStreamReader& reader)
+{
+	QStringRef tagName = reader.name();
+	doc->markersMap.clear();
+	markeredItemsList.clear();
+	markeredMarkersList.clear();
+	while(!reader.atEnd() && !reader.hasError())
+	{
+		reader.readNext();
+		if (reader.isEndElement() && reader.name() == tagName)
+			break;
+		if(reader.isStartElement() && reader.name() == "Marker")
+		{
+			ScXmlStreamAttributes attrs = reader.scAttributes();
+			MarkerData d;
+			d.itemName = "";
+			d.itemPtr = NULL;
+			d.mrkPtr = NULL;
+			d.strPtr = NULL;
+
+			QString label = "";
+			if (attrs.hasAttribute("label"))
+				label = attrs.valueAsString("label");
+
+			MarkerType type = MARKERNoType;
+			if (attrs.hasAttribute("type"))
+				type = (MarkerType) attrs.valueAsInt("type");
+
+			if (label != "" && type != MARKERNoType)
+			{
+				Marker* mark = new Marker;
+				mark->label=attrs.valueAsString("label");
+				mark->setType((MarkerType) attrs.valueAsInt("type"));
+				doc->markersMap.insert(mark->label, mark);
+
+				if (type == MARKERVariableTextType && attrs.hasAttribute("str"))
+					mark->setString(attrs.valueAsString("str"));
+				if (type == MARKER2ItemType && attrs.hasAttribute("itemName"))
+				{
+					QString itemName = attrs.valueAsString("itemName");
+					markeredItemsList.insert(itemName, mark);
+				}
+				if (type == MARKER2MarkerType && attrs.hasAttribute("MARKlabel"))
+				{
+					QString mark2Label = attrs.valueAsString("MARKlabel");
+					MarkerType mark2Type = (MarkerType) attrs.valueAsInt("MARKtype");
+					Marker* mark2 = doc->getMarkerDefinied(mark2Label, mark2Type);
+					if (mark2 != NULL) //marker is not defined yet, insert into temp list for update to pointers later
+						mark->setMarker(mark2);
+					else
+					{
+						QMap<QString, MarkerType> mark2map;
+						mark2map.insert(mark2Label, mark2Type);
+						markeredMarkersList.insert(mark, mark2map);
+					}
+				}
+			}
+		}
+	}
+	return !reader.hasError();
+}
+
 bool Scribus150Format::readSections(ScribusDoc* doc, ScXmlStreamReader& reader)
 {
 	QStringRef tagName = reader.name();
@@ -3214,6 +3295,25 @@
 				doc->Items = DItems;
 			}
 		}
+		if (tName == "MARKER")
+		{
+			if (newItem->asTextFrame())
+			{
+				QString l = tAtt.valueAsString("label");
+				MarkerType t = (MarkerType) tAtt.valueAsInt("type");
+				Marker* mark = m_Doc->getMarkerDefinied(l, t);
+				if (mark == NULL)
+					qDebug() << "Undefinied marker label ["<< l << "] type " << t;
+				else
+				{
+					//set pointer to item holds marker in his text
+					if (t == MARKERAnchorType)
+						mark->setItemPtr(newItem);
+					mark->OwnPage = newItem->OwnPage;
+					newItem->itemText.insertMarker(mark, newItem->itemText.length());
+				}
+			}
+		}
 		if (tName == "WeldEntry")
 		{
 			PageItem::weldingInfo wInf;
@@ -4535,6 +4635,9 @@
 	itemNextF.clear();
 	WeldItems.clear();
 	WeldID.clear();
+	markeredItemsList.clear();
+	markeredMarkersList.clear();
+	
 
  	QString f(readSLA(fileName));
 	if (f.isEmpty())
@@ -5265,3 +5368,51 @@
 	*num2 = counter2;
 	return success;
 }
+
+void Scribus150Format::updateMarkersPtr() //after document load items pointers should be updated in markeredItemList
+{
+	if (!markeredItemsList.isEmpty())
+	{
+		QMap<QString,Marker*>::Iterator markIt;
+		for (markIt = markeredItemsList.begin(); markIt != markeredItemsList.end(); ++markIt)
+		{
+			QString itemName = markIt.key();
+			Marker* marker = markIt.value();
+			if (m_Doc->itemNameExists(itemName))
+			{
+				marker->setItemPtr(m_Doc->getItemFromName(itemName));
+				marker->setString(QString("%1").arg(marker->getItemPtr()->OwnPage +1));
+			}
+			else
+			{
+				qWarning() << "wrong marker [" << marker->label << "] data - item name [" << itemName << "] not exists - DELETING MARKER";
+				if (!m_Doc->eraseMarker(marker))
+					qWarning() << "Erase marker [" << marker->label << "] failed - was it definied?";
+			}
+		}
+	}
+	if (!markeredMarkersList.isEmpty())
+	{
+		QMap<Marker*,QMap<QString, MarkerType> >::iterator markIt;
+		for (markIt = markeredMarkersList.begin(); markIt != markeredMarkersList.end(); ++markIt)
+		{
+			Marker* mark = markIt.key();
+			QMap<QString, MarkerType> mark2map = markIt.value();
+			QString label2 = mark2map.begin().key();
+			MarkerType type2 = mark2map.begin().value();
+			Marker* mark2 = m_Doc->getMarkerDefinied(label2, type2);
+			if (mark2 != NULL)
+			{
+				mark->setMarker(mark2);
+				mark->setString(QString("%1").arg(mark2->getItemPtr()->OwnPage +1));
+			}
+			else
+			{
+				qWarning() << "wrong marker [" << mark->label << "] data - pointed merker name [" << label2 << "] not exists - DELETING MARKER";
+				if (!m_Doc->eraseMarker(mark))
+					qWarning() << "Erase marker [" << mark->label << "] failed - was it definied?";
+
+			}
+		}
+	}
+}
Index: scribus/scribus.h
===================================================================
--- scribus/scribus.h	(wersja 17188)
+++ scribus/scribus.h	(kopia robocza)
@@ -74,6 +74,7 @@
 class GuideManager;
 class HelpBrowser;
 class LayerPalette;
+class MarkersManager;
 class Measurements;
 class ScMWMenuManager;
 class ModeToolBar;
@@ -208,6 +209,7 @@
 	GuideManager *guidePalette;
 	CharSelect *charPalette;
 	PropertiesPalette *propertiesPalette;
+	MarkersManager *markersManager;
 	NodePalette *nodePalette;
 	OutlinePalette *outlinePalette;
 	Biblio *scrapbookPalette;
@@ -611,6 +613,20 @@
 	FormatsManager *formatsManager;
 
 	QPointer<HelpBrowser> helpBrowser;
+
+public slots:
+	//insert marker
+	void slotInsertMarker2Marker() { insertMarker(MARKER2MarkerType); }
+	void slotInsertMarkerAnchor() { insertMarker(MARKERAnchorType); }
+	void slotInsertMarkerVariableText() { insertMarker(MARKERVariableTextType); }
+	void slotInsertMarkerItem() { insertMarker(MARKER2ItemType); }
+	void slotInsertMarkerFootnote() { insertMarker(MARKERFootnoteType); }
+	void slotInsertMarkerEndnote() { insertMarker(MARKEREndnoteType); }
+	void slotInsertMarkerIndex() { insertMarker(MARKERIndexType); }
+	void slotEditMarker();
+	void slotUpdateMarkers();
+private:
+	void insertMarker(MarkerType);
 };
 
 #endif
Index: scribus/CMakeLists.txt
===================================================================
--- scribus/CMakeLists.txt	(wersja 17188)
+++ scribus/CMakeLists.txt	(kopia robocza)
@@ -85,6 +85,11 @@
   ui/inserttablerowsdialog.ui
   ui/latexeditor.ui
   ui/newmarginwidgetbase.ui
+ui/marker2item.ui
+ui/marker2marker.ui
+ui/markeranchor.ui
+ui/markervariabletext.ui
+ui/markersmanager.ui
   ui/measurementsbase.ui
   ui/multipleduplicate.ui
   ui/multiprogressdialog.ui
@@ -204,6 +209,7 @@
   latexhelpers.h
   loadsaveplugin.h
   menumanager.h
+markers.h
   navigator.h
   observable.h
   pageitem.h
@@ -310,6 +316,12 @@
   ui/latexeditor.h
   ui/layers.h
   ui/loremipsum.h
+ui/markerinsertdlgbase.h
+ui/marker2item.h
+ui/marker2marker.h
+ui/markeranchor.h
+ui/markervariabletext.h
+ui/markersmanager.h
   ui/margindialog.h
   ui/marginpresetlayout.h
   ui/marginwidget.h
@@ -734,6 +746,11 @@
   ui/linecombo.cpp
   ui/linkbutton.cpp
   ui/loremipsum.cpp
+ui/marker2item.cpp
+ui/marker2marker.cpp
+ui/markeranchor.cpp
+ui/markervariabletext.cpp
+ui/markersmanager.cpp
   ui/margindialog.cpp
   ui/marginpresetlayout.cpp
   ui/marginwidget.cpp
markers5.patch (102,345 bytes)   

jghali

2012-01-10 14:43

administrator   ~0027506

Thanks, your patch is ok now.

cezaryece

2012-06-04 09:55

updater   ~0028066

Current state of marks feature is in git repo (branch footnotes).
Details in report http://bugs.scribus.net/view.php?id=10730

cezaryece

2012-07-03 10:12

updater   ~0028353

Branch "footnotes" has that feature inside as code background for notes.

Issue History

Date Modified Username Field Change
2011-12-09 14:01 cezaryece New Issue
2011-12-09 14:01 cezaryece File Added: markers.patch
2011-12-09 14:28 cezaryece File Added: markers.jpg
2011-12-09 14:28 cezaryece Note Added: 0027345
2011-12-18 12:50 jghali Note Added: 0027365
2011-12-19 12:43 cezaryece File Added: markers2.patch
2011-12-19 12:43 cezaryece Note Added: 0027370
2012-01-04 19:38 cbradney Note Added: 0027453
2012-01-04 20:25 jghali Note Added: 0027455
2012-01-05 08:39 cezaryece Note Added: 0027460
2012-01-05 08:39 cezaryece File Added: markers3.patch
2012-01-05 16:53 Mike Note Added: 0027464
2012-01-05 22:20 jghali Note Added: 0027468
2012-01-09 11:20 cezaryece Note Added: 0027497
2012-01-09 11:20 cezaryece File Added: markers4.patch
2012-01-09 12:38 jghali Note Added: 0027498
2012-01-09 19:47 cbradney Note Added: 0027500
2012-01-10 10:05 cezaryece Note Added: 0027503
2012-01-10 10:06 cezaryece File Added: markers5.patch
2012-01-10 14:43 jghali Note Added: 0027506
2012-06-04 09:55 cezaryece Note Added: 0028066
2012-07-03 10:12 cezaryece Note Added: 0028353
2012-07-03 10:12 cezaryece Status new => closed
2012-07-03 10:12 cezaryece Assigned To => cezaryece
2012-07-03 10:12 cezaryece Resolution open => suspended