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=" <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(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(doc->arrowStyles().size()))) @@ -5122,6 +5151,7 @@ pstyle.setNumOther(static_cast(attrs.valueAsInt("NumeartionOther"))); if (attrs.hasAttribute("NumerationHigher")) pstyle.setNumHigher(static_cast(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 &getReplacedFonts, QList &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 *items = 0); + bool writeObject(ScribusDoc *doc, ScXmlStreamWriter& docu, const QString& baseDir, ItemSelection master, QList *items, PageItem* item); void SetItemProps(ScXmlStreamWriter& docu, PageItem* item, const QString& baseDir); QMap 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 *some_items) { uint ObCount = maxC; QList *items = NULL; QList 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 *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 #include +#include #include #include #include @@ -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();