Index: scribus/loadsaveplugin.cpp
===================================================================
--- scribus/loadsaveplugin.cpp	(Revision 22369)
+++ scribus/loadsaveplugin.cpp	(Arbeitskopie)
@@ -437,6 +437,14 @@
 	return QImage();
 }
 
+bool LoadSavePlugin::writeObject(ScribusDoc *doc, ScXmlStreamWriter& docu, const QString& baseDir, PageItem * item) {
+	return false;
+}
+bool LoadSavePlugin::readObject(ScribusDoc *doc, ScXmlStreamReader& reader, const QString& baseDir, PageItem **item) {
+	return false;
+}
+
+
 bool FileFormat::loadFile(const QString & fileName, int flags, int index) const
 {
 	if (plug && load)
@@ -498,6 +506,8 @@
 {
 }
 
+
+
 bool FileFormat::loadElements(const QString & data, QString fileDir, int toLayer, double Xp_in, double Yp_in, bool loc) const
 {
 	return (plug && load) ? plug->loadElements(data, fileDir, toLayer, Xp_in, Yp_in, loc) : false;
@@ -573,5 +583,13 @@
 	return (plug && load && thumb) ? plug->readThumbnail(fileName) : QImage();
 }
 
+bool FileFormat::writeObject(ScribusDoc *doc, ScXmlStreamWriter& docu, const QString& baseDir, PageItem * item) const {
+	qDebug() << "FileFormat::writeObject()";
+	return (plug && load) ? plug->writeObject(doc, docu, baseDir, item) : false;
+}
+bool FileFormat::readObject(ScribusDoc *doc, ScXmlStreamReader& reader, const QString& baseDir, PageItem **item) const {
+	qDebug() << "FileFormat::readObject()";
+	return (plug && load) ? plug->readObject(doc, reader, baseDir, item) : false;
+}
 
 
Index: scribus/loadsaveplugin.h
===================================================================
--- scribus/loadsaveplugin.h	(Revision 22369)
+++ scribus/loadsaveplugin.h	(Arbeitskopie)
@@ -22,7 +22,10 @@
 #include "scfonts.h"
 #include "scribusdoc.h"
 #include "undomanager.h"
+#include "scxmlstreamwriter.h"
+#include "scxmlstreamreader.h"
 
+
 /*!
  * @brief Superclass for all file import/export/load/save plugins
  *
@@ -116,6 +119,9 @@
 		virtual bool readPageCount(const QString& fileName, int *num1, int *num2, QStringList & masterPageNames);
 		virtual QImage readThumbnail(const QString& fileName);
 		
+		virtual bool writeObject(ScribusDoc *doc, ScXmlStreamWriter& docu, const QString& baseDir, PageItem * item);
+		virtual bool readObject(ScribusDoc *doc, ScXmlStreamReader& reader, const QString& baseDir, PageItem **item);
+		
 	protected:
 
 		/// Check a loadFlags combination
@@ -258,6 +264,9 @@
 		// this format.
 		LoadSavePlugin * plug;
 //		LoadSavePlugin * const plug;
+		
+		bool writeObject(ScribusDoc *doc, ScXmlStreamWriter& docu, const QString& baseDir, PageItem * item) const;
+		bool readObject(ScribusDoc *doc, ScXmlStreamReader& reader, const QString& baseDir, PageItem **item) const;
 };
 
 
Index: scribus/plugins/fileloader/scribus150format/scribus150format.cpp
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format.cpp	(Revision 22369)
+++ scribus/plugins/fileloader/scribus150format/scribus150format.cpp	(Arbeitskopie)
@@ -3698,10 +3698,33 @@
 	return true;
 }
 
-bool Scribus150Format::readObject(ScribusDoc* doc, ScXmlStreamReader& reader, ItemInfo& info, const QString& baseDir, bool loadPage, QString renamedPageName)
+// Why making it easy when complicated works too? ... Why not simply return PageItem ...
+// This call comes from extern. (probably scribus.cpp)
+// The PageItem serialized in reader must have the appropriate Layer set.
+bool Scribus150Format::readObject(ScribusDoc *doc, ScXmlStreamReader& reader, const QString& baseDir, PageItem **item) {
+	//qDebug() << "Scribus150Format::readObject()    item = " << (uint64_t)((void*)(item));
+	ScXmlStreamAttributes attrs = reader.scAttributes();
+	LayerToPaste = attrs.valueAsInt("LAYER");
+	ItemInfo info;
+	bool retV = readObject(doc, reader, info, baseDir, false, QString());
+	//qDebug() << "Scribus150Format::readObject()    retV = " << retV;
+	if (retV)
+		*item = info.item;
+	//qDebug() << "Scribus150Format::readObject()    item = " << (*item)->itemName();
+	return retV;
+}
+
+// This call comes from intern (scribus150format.cpp)
+bool Scribus150Format::readObject(ScribusDoc *doc, ScXmlStreamReader& reader, ItemInfo& info, const QString& baseDir, bool loadPage, QString renamedPageName)
 {
 	QStringRef tagName = reader.name();
 	ScXmlStreamAttributes attrs = reader.scAttributes();
+	/*qDebug() << "attrs: size=" << attrs.size();
+	if (!attrs.isEmpty()) {
+		QXmlStreamAttribute qxsa = attrs.first();
+		qDebug() << "    Name  = " << qxsa.name();
+		qDebug() << "    Value = " << qxsa.value();
+	}*/
 
 	if (!loadPage)
 	{
@@ -3728,6 +3751,7 @@
 	}
 	layerFound = false;
 	clipPath = "";
+	//qDebug() << "Scribus150Format::readObject(intern)    beep. ItemKind=" <<itemKind;
 	PageItem* newItem = pasteItem(doc, attrs, baseDir, itemKind, pagenr);
 	newItem->setRedrawBounding();
 	if (tagName == "MASTEROBJECT")
@@ -4807,6 +4831,7 @@
 	QColor tmpc;
 	PageItem *currItem=NULL;
 	QString tmp, clPath;
+	//qDebug() << "Scribus150Format::pasteItem(intern)    beep0. itemType=" << pt << "   (Could be " << attrs.valueAsInt("PTYPE") << ".)";
 	switch (pt)
 	{
 	// OBSOLETE CR 2005-02-06
@@ -4915,6 +4940,7 @@
 	case PageItem::NoteFrame:
 	case PageItem::TextFrame:
 		z = doc->itemAdd(pt, PageItem::Unspecified, x, y, w, h, pw, CommonStrings::None, Pcolor, itemKind);
+		//qDebug() << "Scribus150Format::pasteItem(intern)    beep2. z=" << z;
 		currItem = doc->Items->at(z);
 		if (pagenr > -2) 
 			currItem->setOwnerPage(pagenr);
@@ -4981,8 +5007,10 @@
 		Q_ASSERT(false);
 		break;
 	}
-
+	//qDebug() << "Scribus150Format::pasteItem(intern)    beep2. pagenr=" << pagenr << ", currItem=" << (uint64_t)((void*)currItem);
+	
 	currItem->setGroupClipping(attrs.valueAsBool("groupClips", true));
+	//qDebug() << "Scribus150Format::pasteItem(intern)    beep25.";
 	currItem->FrameType = attrs.valueAsInt("FRTYPE", 0);
 	int startArrowIndex = attrs.valueAsInt("startArrowIndex", 0);
 	if ((startArrowIndex < 0) || (startArrowIndex > static_cast<int>(doc->arrowStyles().size())))
@@ -4990,6 +5018,7 @@
 		qDebug() << QString("scribus150format: invalid arrow index: %").arg(startArrowIndex);
 		startArrowIndex = 0;
 	}
+	//qDebug() << "Scribus150Format::pasteItem(intern)    beep3.";
 	currItem->setStartArrowIndex(startArrowIndex);
 	int endArrowIndex = attrs.valueAsInt("endArrowIndex", 0);
 	if ((endArrowIndex < 0) || (endArrowIndex > static_cast<int>(doc->arrowStyles().size())))
@@ -5122,6 +5151,7 @@
 		pstyle.setNumOther(static_cast<bool>(attrs.valueAsInt("NumeartionOther")));
 	if (attrs.hasAttribute("NumerationHigher"))
 		pstyle.setNumHigher(static_cast<bool>(attrs.valueAsInt("NumerationHigher")));
+	//qDebug() << "Scribus150Format::pasteItem(intern)    beep3.";
 	currItem->itemText.setDefaultStyle(pstyle);
 
 	if (attrs.hasAttribute("PSTYLE"))
@@ -5149,6 +5179,8 @@
 	currItem->setIsAnnotation( attrs.valueAsInt("ANNOTATION", 0));
 	currItem->annotation().setType( attrs.valueAsInt("ANTYPE", 0));
 	QString AnName = attrs.valueAsString("ANNAME","");
+	//qDebug() << "Scribus150Format::pasteItem(intern)    beep38. XML:ANNAME =      " << AnName;
+	//qDebug() << "Scribus150Format::pasteItem(intern)    beep39. currItem->AnName =" << currItem->itemName();
 	if (!AnName.isEmpty())
 	{
 		if (currItem->itemName() == AnName)
@@ -5159,6 +5191,7 @@
 			currItem->AutoName = false;
 		}
 	}
+	//qDebug() << "Scribus150Format::pasteItem(intern)    beep4. currItem->AutoName = " << currItem->AutoName;
 
 	currItem->annotation().setAction( attrs.valueAsString("ANACTION","") );
 	currItem->annotation().setE_act ( attrs.valueAsString("ANEACT","") );
Index: scribus/plugins/fileloader/scribus150format/scribus150format.h
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format.h	(Revision 22369)
+++ scribus/plugins/fileloader/scribus150format/scribus150format.h	(Arbeitskopie)
@@ -4,8 +4,8 @@
 a copyright and/or license notice that predates the release of Scribus 1.3.2
 for which a new license (GPL+exception) is in place.
 */
-#ifndef SCRIBUS134FORMAT_H
-#define SCRIBUS134FORMAT_H
+#ifndef SCRIBUS150FORMAT_H
+#define SCRIBUS150FORMAT_H
 
 #include "pluginapi.h"
 #include "loadsaveplugin.h"
@@ -63,9 +63,13 @@
 		virtual bool readColors(const QString& fileName, ColorList & colors);
 		virtual bool readPageCount(const QString& fileName, int *num1, int *num2, QStringList & masterPageNames);
 		virtual void getReplacedFontData(bool & getNewReplacement, QMap<QString,QString> &getReplacedFonts, QList<ScFace> &getDummyScFaces);
-
+		
+		
+		bool writeObject(ScribusDoc *doc, ScXmlStreamWriter& docu, const QString& baseDir, PageItem * item); // Gets overloaded by writeObject(...., ItemSelection master)
+		bool readObject(ScribusDoc *doc, ScXmlStreamReader& reader, const QString& baseDir, PageItem **item);
+	
 	private:
-
+	
 		enum ItemSelection {
 			ItemSelectionMaster = 0,
 			ItemSelectionPage   = 1,
@@ -190,6 +194,7 @@
 
 		void WritePages(ScribusDoc *doc, ScXmlStreamWriter& docu, QProgressBar *dia2, uint maxC, bool master);
 		void WriteObjects(ScribusDoc *doc, ScXmlStreamWriter& docu, const QString& baseDir, QProgressBar *dia2, uint maxC, ItemSelection master, QList<PageItem*> *items = 0);
+		bool writeObject(ScribusDoc *doc, ScXmlStreamWriter& docu, const QString& baseDir, ItemSelection master, QList<PageItem*> *items, PageItem* item);
 		void SetItemProps(ScXmlStreamWriter& docu, PageItem* item, const QString& baseDir);
 
 		QMap<QString, QString> parStyleMap;
Index: scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp	(Revision 22369)
+++ scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp	(Arbeitskopie)
@@ -49,7 +49,7 @@
 {
 	QString fileDir = ScPaths::applicationDataDir();
 	QString documentStr;
-	documentStr.reserve(524288);
+	documentStr.reserve(524288); // FIXME: Magic Number
 	ScXmlStreamWriter writer(&documentStr);
 	writer.setAutoFormatting(true);
 //	writer.writeStartDocument();
@@ -1761,12 +1761,18 @@
 	}
 }
 
+
+bool  Scribus150Format::writeObject(ScribusDoc *doc, ScXmlStreamWriter& docu, const QString& baseDir, PageItem* item) {
+	qDebug() << "Scribus150Format::writeObject()";
+	return writeObject(doc, docu, baseDir, ItemSelectionElements, NULL, item);
+}
+
 void Scribus150Format::WriteObjects(ScribusDoc *doc, ScXmlStreamWriter& docu, const QString& baseDir, QProgressBar *dia2, uint maxC, ItemSelection master, QList<PageItem*> *some_items)
 {
 	uint ObCount = maxC;
 	QList<PageItem*> *items = NULL;
 	QList<PageItem*> itemList;
-	PageItem *item = NULL;
+	PageItem *item;
 	uint objects = 0;
 	switch (master)
 	{
@@ -1800,6 +1806,13 @@
 		if (dia2 != 0)
 			dia2->setValue(ObCount);
 		item = items->at(j);
+		writeObject(doc, docu, baseDir, master, items, item);
+	}
+}
+
+
+bool Scribus150Format::writeObject(ScribusDoc *doc, ScXmlStreamWriter& docu, const QString& baseDir, ItemSelection master, QList<PageItem*> *items, PageItem* item)
+{
 		switch (master)
 		{
 			case ItemSelectionMaster:
@@ -2015,7 +2028,7 @@
 			else
 				docu.writeAttribute("NEXTITEM", -1);
 			
-			if (item->prevInChain() != 0 && items->contains(item->prevInChain()))
+			if (item->prevInChain() != 0 && items && items->contains(item->prevInChain()))
 				docu.writeAttribute("BACKITEM", qHash(item->prevInChain()) & 0x7FFFFFFF);
 			else
 			{
@@ -2467,7 +2480,7 @@
 			docu.writeEndElement();
 		}
 		docu.writeEndElement();
-	}
+	return true;
 }
 
 void Scribus150Format::SetItemProps(ScXmlStreamWriter& docu, PageItem* item, const QString& baseDir)
Index: scribus/scribus.cpp
===================================================================
--- scribus/scribus.cpp	(Revision 22369)
+++ scribus/scribus.cpp	(Arbeitskopie)
@@ -23,6 +23,7 @@
 
 #include <QAction>
 #include <QApplication>
+#include <QBuffer>
 #include <QByteArray>
 #include <QCloseEvent>
 #include <QColor>
@@ -150,6 +151,8 @@
 #include "scribusdoc.h"
 #include "scribusview.h"
 #include "scribuswin.h"
+#include "scxmlstreamreader.h"
+#include "scxmlstreamwriter.h"
 #include "selection.h"
 #include "serializer.h"
 #include "styleoptions.h"
@@ -4552,6 +4555,63 @@
 	close();
 }
 
+
+PageItem* ScribusMainWindow::slotDuplicateSingle(PageItem * source, QString *newname) {
+	// Seems the best way to serialize object and re-include it. 
+	// This is similar to what slotEditCopy+slotEditPaste would do, but 
+	// they use the system clipboard and copy a whole selection.
+	// Instead of serializing the strings one could have mad a simple
+	// copy of the PageItem using it's constructor.
+	// But this way we can be sure to transfer
+	// all the information.
+	
+	const FileFormat *fmt = LoadSavePlugin::getFormatById(FORMATID_SLA150IMPORT);
+	if (!fmt) {
+		qDebug() << "Couldn't find LoadSavePlugin.";
+		return NULL;
+	}
+	fmt->setupTargets(doc, 0, doc->scMW(), 0, &(PrefsManager::instance()->appPrefs.fontPrefs.AvailFonts));
+	
+	
+	QString XMLBuffer = QString("");
+	//qDebug() << "slotDuplicateSingle(): XMLBuffer: " << XMLBuffer;
+	ScXmlStreamWriter docu (&XMLBuffer);
+	//docu.writeComment("abc\"defg\n");
+	bool res = fmt->writeObject(doc, docu, ScPaths::applicationDataDir(), source);
+	//qDebug() << "slotDuplicateSingle(): " << res << " --> XMLBuffer: " << XMLBuffer;
+	
+	if (!res || !XMLBuffer.count()) {
+		qDebug() << "slotDuplicateSingle(): Couldn't serialize PageItem.";
+		return NULL;
+	}
+	
+	//qDebug() << "slotDuplicateSingle(): new XMLBuffer:" << XMLBuffer;
+	ScXmlStreamReader reader(XMLBuffer.toUtf8().constData());
+
+	while (reader.readNext() != ScXmlStreamReader::StartElement) {}
+	
+	ScXmlStreamAttributes sxsa = reader.scAttributes();
+	
+	assert (!sxsa.isEmpty());
+	/*
+	qDebug() << "slotDuplicateSingle(): attrs: size=" << sxsa.size();
+	QXmlStreamAttribute qxsa = sxsa.first();
+	qDebug() << "slotDuplicateSingle():     Name  = " << qxsa.name();
+	qDebug() << "slotDuplicateSingle():     Value = " << qxsa.value();
+	*/
+	PageItem *retV;
+	fmt->readObject(doc, reader, ScPaths::applicationDataDir(), &retV);
+	
+	if (newname != NULL && !newname->isEmpty())
+		retV->setItemName(*newname);
+	retV->setXYPos(source->xPos(), source->yPos());
+	
+	slotDocCh();
+	
+	return retV;
+}
+
+
 void ScribusMainWindow::slotEditCut()
 {
 	if (!HaveDoc)
@@ -4681,10 +4741,8 @@
 	{
 		if ((currItem->isSingleSel) && (currItem->isGroup()))
 			return;
-		//do not copy notes frames
-		if (doc->m_Selection->count() ==1 && currItem->isNoteFrame())
-			return;
-		//deselect notesframes
+		
+		// do not copy notes frames -> deselect them
 		Selection tempSelection(*(doc->m_Selection));
 		for (int i = 0; i < doc->m_Selection->count(); ++i)
 		{
@@ -4693,7 +4751,10 @@
 		}
 		if (tempSelection.count() < doc->m_Selection->count())
 			*(doc->m_Selection) = tempSelection;
-
+		
+		if (doc->m_Selection->isEmpty() == 0)
+			return;
+		
 		ScriXmlDoc ss;
 		QString BufferS = ss.WriteElem(doc, doc->m_Selection);
 		if (!internalCopy)
@@ -4949,7 +5010,7 @@
 		else
 			currItem->update();
 		view->DrawNew();
-	}
+	} // if appMode == modeEdit/modeEditTable && selItem->isTextFrame()/isTable()
 	else
 	{
 		if (ScMimeData::clipboardHasScribusElem() || ScMimeData::clipboardHasScribusFragment() || internalCopy)
Index: scribus/scribus.h
===================================================================
--- scribus/scribus.h	(Revision 22369)
+++ scribus/scribus.h	(Arbeitskopie)
@@ -371,6 +371,8 @@
 	bool doPrint(PrintOptions &options, QString& error);
 	/** \brief exits the application */
 	void slotFileQuit();
+	/** \brief Duplicate a single PageItem. */
+	PageItem* slotDuplicateSingle(PageItem * source, QString *newname);
 	/** \brief put the marked text/object into the clipboard and remove
 	 * it from the document */
 	void slotEditCut();
