Scribus Developer Documentation - API
logo-pen

Scribus Developer Documentation - API

oodrawimp.cpp

Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 #include <QWidget>
00008 #include <QFile>
00009 #include <QRegExp>
00010 #include <QCursor>
00011 #include <QDir>
00012 #include <QString>
00013 #include <QDomElement>
00014 #include <QDrag>
00015 #include <QMimeData>
00016 #include <cmath>
00017 
00018 #include "oodrawimp.h"
00019 
00020 #include "scconfig.h"
00021 
00022 #include "color.h"
00023 #include "commonstrings.h"
00024 #include "customfdialog.h"
00025 #include "fileunzip.h"
00026 #include "fpointarray.h"
00027 #include "menumanager.h"
00028 #include "pageitem.h"
00029 #include "pluginmanager.h"
00030 #include "prefscontext.h"
00031 #include "prefsfile.h"
00032 #include "prefsmanager.h"
00033 #include "prefstable.h"
00034 #include "propertiespalette.h"
00035 #include "sccolorengine.h"
00036 #include "scraction.h"
00037 #include "scribusXml.h"
00038 #include "scribuscore.h"
00039 #include "scribusdoc.h"
00040 #include "selection.h"
00041 #include "serializer.h"
00042 #include "stylestack.h"
00043 #include "undomanager.h"
00044 #include "util.h"
00045 #include "util_icon.h"
00046 #include "util_math.h"
00047 
00048 
00049 using namespace std;
00050 
00051 int oodrawimp_getPluginAPIVersion()
00052 {
00053     return PLUGIN_API_VERSION;
00054 }
00055 
00056 ScPlugin* oodrawimp_getPlugin()
00057 {
00058     OODrawImportPlugin* plug = new OODrawImportPlugin();
00059     Q_CHECK_PTR(plug);
00060     return plug;
00061 }
00062 
00063 void oodrawimp_freePlugin(ScPlugin* plugin)
00064 {
00065     OODrawImportPlugin* plug = dynamic_cast<OODrawImportPlugin*>(plugin);
00066     Q_ASSERT(plug);
00067     delete plug;
00068 }
00069 
00070 OODrawImportPlugin::OODrawImportPlugin() :
00071     LoadSavePlugin(),
00072     importAction(new ScrAction(ScrAction::DLL, QPixmap(), QPixmap(), "", QKeySequence(), this))
00073 {
00074     // Set action info in languageChange, so we only have to do
00075     // it in one place. This includes registering file formats.
00076     languageChange();
00077 }
00078 
00079 void OODrawImportPlugin::addToMainWindowMenu(ScribusMainWindow *mw)
00080 {
00081     // Then hook up the action
00082     importAction->setEnabled(true);
00083     connect( importAction, SIGNAL(triggered()), SLOT(import()) );
00084     mw->scrMenuMgr->addMenuItem(importAction, "FileImport");
00085 }
00086 
00087 OODrawImportPlugin::~OODrawImportPlugin()
00088 {
00089     unregisterAll();
00090     // note: importAction is automatically deleted by Qt
00091 };
00092 
00093 void OODrawImportPlugin::languageChange()
00094 {
00095     importAction->setText( tr("Import &OpenOffice.org Draw..."));
00096     // (Re)register file formats
00097     unregisterAll();
00098     registerFormats();
00099 }
00100 
00101 const QString OODrawImportPlugin::fullTrName() const
00102 {
00103     return QObject::tr("OpenOffice.org Draw Importer");
00104 }
00105 
00106 const ScActionPlugin::AboutData* OODrawImportPlugin::getAboutData() const
00107 {
00108     AboutData* about = new AboutData;
00109     about->authors = "Franz Schmid <franz@scribus.info>";
00110     about->shortDescription = tr("Imports OpenOffice.org Draw Files");
00111     about->description = tr("Imports most OpenOffice.org Draw files into the current document, converting their vector data into Scribus objects.");
00112     about->license = "GPL";
00113     Q_CHECK_PTR(about);
00114     return about;
00115 }
00116 
00117 void OODrawImportPlugin::deleteAboutData(const AboutData* about) const
00118 {
00119     Q_ASSERT(about);
00120     delete about;
00121 }
00122 
00123 void OODrawImportPlugin::registerFormats()
00124 {
00125     QString odtName = tr("OpenDocument 1.0 Draw", "Import/export format name");
00126     FileFormat odtformat(this);
00127     odtformat.trName = odtName; // Human readable name
00128     odtformat.formatId = FORMATID_ODGIMPORT;
00129     odtformat.filter = odtName + " (*.odg *.ODG)"; // QFileDialog filter
00130     odtformat.nameMatch = QRegExp("\\.odg$", Qt::CaseInsensitive);
00131     odtformat.load = true;
00132     odtformat.save = false;
00133     odtformat.mimeTypes = QStringList("application/vnd.oasis.opendocument.graphics"); // MIME types
00134     odtformat.priority = 64; // Priority
00135     registerFormat(odtformat);
00136 
00137     QString sxdName = tr("OpenOffice.org 1.x Draw", "Import/export format name");
00138     FileFormat sxdformat(this);
00139     sxdformat.trName = sxdName; // Human readable name
00140     sxdformat.formatId = FORMATID_SXDIMPORT;
00141     sxdformat.filter = sxdName + " (*.sxd *.SXD)"; // QFileDialog filter
00142     sxdformat.nameMatch = QRegExp("\\.sxd$", Qt::CaseInsensitive);
00143     sxdformat.load = true;
00144     sxdformat.save = false;
00145     sxdformat.mimeTypes = QStringList("application/vnd.sun.xml.draw"); // MIME types
00146     sxdformat.priority = 64; // Priority
00147     registerFormat(sxdformat);
00148 }
00149 
00150 bool OODrawImportPlugin::fileSupported(QIODevice* /* file */, const QString & fileName) const
00151 {
00152     // TODO: try to identify .sxd / .odt files
00153     return true;
00154 }
00155 
00156 bool OODrawImportPlugin::loadFile(const QString & fileName, const FileFormat &, int flags, int /*index*/)
00157 {
00158     // For this plugin, right now "load" and "import" are the same thing
00159     return import(fileName, flags);
00160 }
00161 
00162 bool OODrawImportPlugin::import(QString fileName, int flags)
00163 {
00164     if (!checkFlags(flags))
00165         return false;
00166     if (fileName.isEmpty())
00167     {
00168         flags |= lfInteractive;
00169         PrefsContext* prefs = PrefsManager::instance()->prefsFile->getPluginContext("OODrawImport");
00170         QString wdir = prefs->get("wdir", ".");
00171         CustomFDialog diaf(ScCore->primaryMainWindow(), wdir, QObject::tr("Open"), QObject::tr("OpenOffice.org Draw (*.sxd *.odg);;All Files (*)"));
00172         if (diaf.exec())
00173         {
00174             fileName = diaf.selectedFile();
00175             prefs->set("wdir", fileName.left(fileName.lastIndexOf("/")));
00176         }
00177         else
00178             return true;
00179     }
00180     m_Doc=ScCore->primaryMainWindow()->doc;
00181     UndoTransaction* activeTransaction = NULL;
00182     bool emptyDoc = (m_Doc == NULL);
00183     if (UndoManager::undoEnabled() && !emptyDoc)
00184     {
00185         activeTransaction = new UndoTransaction(UndoManager::instance()->beginTransaction(m_Doc->currentPage()->getUName(),
00186                                                                                           Um::IImageFrame,
00187                                                                                           Um::ImportOOoDraw,
00188                                                                                           fileName, Um::IImportOOoDraw));
00189     }
00190     else if (UndoManager::undoEnabled() && emptyDoc)
00191         UndoManager::instance()->setUndoEnabled(false);
00192     OODPlug dia(m_Doc);
00193     bool importDone = dia.import(fileName, flags);
00194     if (activeTransaction)
00195     {
00196         activeTransaction->commit();
00197         delete activeTransaction;
00198         activeTransaction = NULL;
00199     }
00200     else if (UndoManager::undoEnabled() && emptyDoc)
00201         UndoManager::instance()->setUndoEnabled(true);
00202     if (dia.importCanceled)
00203     {
00204         if ((!importDone) || (dia.importFailed))
00205             QMessageBox::warning(ScCore->primaryMainWindow(), CommonStrings::trWarning, tr("The file could not be imported"), 1, 0, 0);
00206         else if (dia.unsupported)
00207             QMessageBox::warning(ScCore->primaryMainWindow(), CommonStrings::trWarning, tr("This file contains some unsupported features"), 1, 0, 0);
00208     }
00209     return importDone;
00210 }
00211 
00212 OODPlug::OODPlug(ScribusDoc* doc)
00213 {
00214     m_Doc=doc;
00215     unsupported = false;
00216     interactive = false;
00217     importFailed = false;
00218     importCanceled = true;
00219     importedColors.clear();
00220     tmpSel=new Selection(this, false);
00221 }
00222 
00223 bool OODPlug::import( QString fileName, int flags )
00224 {
00225     bool importDone = false;
00226     interactive = (flags & LoadSavePlugin::lfInteractive);
00227     QString f, f2, f3;
00228     if ( !QFile::exists(fileName) )
00229         return false;
00230 //  m_styles.setAutoDelete( true );
00231     FileUnzip* fun = new FileUnzip(fileName);
00232     stylePath   = fun->getFile("styles.xml");
00233     contentPath = fun->getFile("content.xml");
00234     metaPath = fun->getFile("meta.xml");
00235     delete fun;
00236     // Qt4 NULL -> isNull()
00237     if ((!stylePath.isNull()) && (!contentPath.isNull()))
00238     {
00239         QString docname = fileName.right(fileName.length() - fileName.lastIndexOf("/") - 1);
00240         docname = docname.left(docname.lastIndexOf("."));
00241         loadText(stylePath, &f);
00242         if(!inpStyles.setContent(f))
00243             return false;
00244         loadText(contentPath, &f2);
00245         if(!inpContents.setContent(f2))
00246             return false;
00247         QFile f1(stylePath);
00248         f1.remove();
00249         QFile f2(contentPath);
00250         f2.remove();
00251         if (!metaPath.isNull())
00252         {
00253             HaveMeta = true;
00254             loadText(metaPath, &f3);
00255             if(!inpMeta.setContent(f3))
00256                 HaveMeta = false;
00257             QFile f3(metaPath);
00258             f3.remove();
00259         }
00260         else
00261             HaveMeta = false;
00262     }
00263     else if ((stylePath.isNull()) && (!contentPath.isNull()))
00264     {
00265         QFile f2(contentPath);
00266         f2.remove();
00267     }
00268     else if ((!stylePath.isNull()) && (contentPath.isNull()))
00269     {
00270         QFile f1(stylePath);
00271         f1.remove();
00272     }
00273     QString CurDirP = QDir::currentPath();
00274     QFileInfo efp(fileName);
00275     QDir::setCurrent(efp.path());
00276     importDone = convert(flags);
00277     QDir::setCurrent(CurDirP);
00278     return importDone;
00279 }
00280 
00281 bool OODPlug::convert(int flags)
00282 {
00283     bool ret = false;
00284     bool isOODraw2 = false;
00285     QDomNode drawPagePNode;
00286     int PageCounter = 0;
00287     QList<PageItem*> Elements;
00288     createStyleMap( inpStyles );
00289     QDomElement docElem = inpContents.documentElement();
00290     QDomNode automaticStyles = docElem.namedItem( "office:automatic-styles" );
00291     if( !automaticStyles.isNull() )
00292         insertStyles( automaticStyles.toElement() );
00293     QDomNode body = docElem.namedItem( "office:body" );
00294     QDomNode drawPage = body.namedItem( "draw:page" );
00295     if ( drawPage.isNull() )
00296     {
00297         QDomNode offDraw = body.namedItem( "office:drawing" );
00298         drawPage = offDraw.namedItem( "draw:page" );
00299         if (drawPage.isNull())
00300         {
00301             QMessageBox::warning( m_Doc->scMW(), CommonStrings::trWarning, tr("This document does not seem to be an OpenOffice Draw file.") );
00302             return false;
00303         }
00304         else
00305         {
00306             isOODraw2 = true;
00307             drawPagePNode = body.namedItem( "office:drawing" );
00308         }
00309     }
00310     else 
00311         drawPagePNode = body;
00312     StyleStack::Mode mode = isOODraw2 ? StyleStack::OODraw2x : StyleStack::OODraw1x;
00313     m_styleStack.setMode( mode );
00314     QDomElement dp = drawPage.toElement();
00315     QDomElement *master = m_styles[dp.attribute( "draw:master-page-name" )];
00316     QDomElement *style = NULL;
00317     QDomElement properties;
00318     if (isOODraw2)
00319     {
00320         style = m_styles[master->attribute( "style:page-layout-name" )];
00321         properties = style->namedItem( "style:page-layout-properties" ).toElement();
00322     }
00323     else
00324     {
00325         style = m_styles[master->attribute( "style:page-master-name" )];
00326         properties = style->namedItem( "style:properties" ).toElement();
00327     }
00328     double width = !properties.attribute( "fo:page-width" ).isEmpty() ? parseUnit(properties.attribute( "fo:page-width" ) ) : 550.0;
00329     double height = !properties.attribute( "fo:page-height" ).isEmpty() ? parseUnit(properties.attribute( "fo:page-height" ) ) : 841.0;
00330     if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
00331         m_Doc->setPage(width, height, 0, 0, 0, 0, 0, 0, false, false);
00332     else
00333     {
00334         if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
00335         {
00336             m_Doc=ScCore->primaryMainWindow()->doFileNew(width, height, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
00337             ScCore->primaryMainWindow()->HaveNewDoc();
00338             ret = true;
00339         }
00340     }
00341     if ((ret) || (!interactive))
00342     {
00343         if (width > height)
00344             m_Doc->PageOri = 1;
00345         else
00346             m_Doc->PageOri = 0;
00347         m_Doc->m_pageSize = "Custom";
00348         QDomNode mpg;
00349         QDomElement metaElem = inpMeta.documentElement();
00350         QDomElement mp = metaElem.namedItem( "office:meta" ).toElement();
00351         mpg = mp.namedItem( "dc:title" );
00352         if (!mpg.isNull())
00353             m_Doc->documentInfo.setTitle(mpg.toElement().text());
00354         mpg = mp.namedItem( "meta:initial-creator" );
00355         if (!mpg.isNull())
00356             m_Doc->documentInfo.setAuthor(mpg.toElement().text());
00357         mpg = mp.namedItem( "dc:description" );
00358         if (!mpg.isNull())
00359             m_Doc->documentInfo.setComments(mpg.toElement().text());
00360         mpg = mp.namedItem( "dc:language" );
00361         if (!mpg.isNull())
00362             m_Doc->documentInfo.setLangInfo(mpg.toElement().text());
00363         mpg = mp.namedItem( "meta:creation-date" );
00364         if (!mpg.isNull())
00365             m_Doc->documentInfo.setDate(mpg.toElement().text());
00366         mpg = mp.namedItem( "dc:creator" );
00367         if (!mpg.isNull())
00368             m_Doc->documentInfo.setContrib(mpg.toElement().text());
00369         mpg = mp.namedItem( "meta:keywords" );
00370         if (!mpg.isNull())
00371         {
00372             QString Keys = "";
00373             for( QDomNode n = mpg.firstChild(); !n.isNull(); n = n.nextSibling() )
00374             {
00375                 Keys += n.toElement().text()+", ";
00376             }
00377             if (Keys.length() > 2)
00378                 m_Doc->documentInfo.setKeywords(Keys.left(Keys.length()-2));
00379         }
00380     }
00381     FPoint minSize = m_Doc->minCanvasCoordinate;
00382     FPoint maxSize = m_Doc->maxCanvasCoordinate;
00383     FPoint cOrigin = m_Doc->view()->canvasOrigin();
00384     m_Doc->view()->Deselect();
00385     Elements.clear();
00386     m_Doc->setLoading(true);
00387     m_Doc->DoDrawing = false;
00388     m_Doc->view()->updatesOn(false);
00389     m_Doc->scMW()->ScriptRunning = true;
00390     qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
00391     if (!m_Doc->PageColors.contains("Black"))
00392         m_Doc->PageColors.insert("Black", ScColor(0, 0, 0, 255));
00393     for( QDomNode drawPag = drawPagePNode.firstChild(); !drawPag.isNull(); drawPag = drawPag.nextSibling() )
00394     {
00395         QDomElement dpg = drawPag.toElement();
00396         if (!interactive)
00397         {
00398             m_Doc->addPage(PageCounter);
00399             m_Doc->view()->addPage(PageCounter);
00400         }
00401         PageCounter++;
00402         m_styleStack.clear();
00403         fillStyleStack( dpg );
00404         QList<PageItem*> el = parseGroup( dpg );
00405         for (int ec = 0; ec < el.count(); ++ec)
00406             Elements.append(el.at(ec));
00407         if ((interactive) && (PageCounter == 1))
00408             break;
00409     }
00410     tmpSel->clear();
00411 //  if ((Elements.count() > 1) && (interactive))
00412     if (Elements.count() == 0)
00413     {
00414         importFailed = true;
00415         if (importedColors.count() != 0)
00416         {
00417             for (int cd = 0; cd < importedColors.count(); cd++)
00418             {
00419                 m_Doc->PageColors.remove(importedColors[cd]);
00420             }
00421         }
00422     }
00423     if (Elements.count() > 1)
00424     {
00425         bool isGroup = true;
00426         int firstElem = -1;
00427         if (Elements.at(0)->Groups.count() != 0)
00428             firstElem = Elements.at(0)->Groups.top();
00429         for (int bx = 0; bx < Elements.count(); ++bx)
00430         {
00431             PageItem* bxi = Elements.at(bx);
00432             if (bxi->Groups.count() != 0)
00433             {
00434                 if (bxi->Groups.top() != firstElem)
00435                     isGroup = false;
00436             }
00437             else
00438                 isGroup = false;
00439         }
00440         if (!isGroup)
00441         {
00442             double minx = 99999.9;
00443             double miny = 99999.9;
00444             double maxx = -99999.9;
00445             double maxy = -99999.9;
00446             uint lowestItem = 999999;
00447             uint highestItem = 0;
00448             for (int a = 0; a < Elements.count(); ++a)
00449             {
00450                 Elements.at(a)->Groups.push(m_Doc->GroupCounter);
00451                 PageItem* currItem = Elements.at(a);
00452                 lowestItem = qMin(lowestItem, currItem->ItemNr);
00453                 highestItem = qMax(highestItem, currItem->ItemNr);
00454                 double lw = currItem->lineWidth() / 2.0;
00455                 if (currItem->rotation() != 0)
00456                 {
00457                     FPointArray pb;
00458                     pb.resize(0);
00459                     pb.addPoint(FPoint(currItem->xPos()-lw, currItem->yPos()-lw));
00460                     pb.addPoint(FPoint(currItem->width()+lw*2.0, -lw, currItem->xPos()-lw, currItem->yPos()-lw, currItem->rotation(), 1.0, 1.0));
00461                     pb.addPoint(FPoint(currItem->width()+lw*2.0, currItem->height()+lw*2.0, currItem->xPos()-lw, currItem->yPos()-lw, currItem->rotation(), 1.0, 1.0));
00462                     pb.addPoint(FPoint(-lw, currItem->height()+lw*2.0, currItem->xPos()-lw, currItem->yPos()-lw, currItem->rotation(), 1.0, 1.0));
00463                     for (uint pc = 0; pc < 4; ++pc)
00464                     {
00465                         minx = qMin(minx, pb.point(pc).x());
00466                         miny = qMin(miny, pb.point(pc).y());
00467                         maxx = qMax(maxx, pb.point(pc).x());
00468                         maxy = qMax(maxy, pb.point(pc).y());
00469                     }
00470                 }
00471                 else
00472                 {
00473                     minx = qMin(minx, currItem->xPos()-lw);
00474                     miny = qMin(miny, currItem->yPos()-lw);
00475                     maxx = qMax(maxx, currItem->xPos()-lw + currItem->width()+lw*2.0);
00476                     maxy = qMax(maxy, currItem->yPos()-lw + currItem->height()+lw*2.0);
00477                 }
00478             }
00479             double gx = minx;
00480             double gy = miny;
00481             double gw = maxx - minx;
00482             double gh = maxy - miny;
00483             PageItem *high = m_Doc->Items->at(highestItem);
00484             int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, gx, gy, gw, gh, 0, m_Doc->toolSettings.dBrush, m_Doc->toolSettings.dPen, true);
00485             PageItem *neu = m_Doc->Items->takeAt(z);
00486             m_Doc->Items->insert(lowestItem, neu);
00487             neu->Groups.push(m_Doc->GroupCounter);
00488             neu->setItemName( tr("Group%1").arg(neu->Groups.top()));
00489             neu->isGroupControl = true;
00490             neu->groupsLastItem = high;
00491             neu->setTextFlowMode(PageItem::TextFlowUsesFrameShape);
00492             for (int a = 0; a < m_Doc->Items->count(); ++a)
00493             {
00494                 m_Doc->Items->at(a)->ItemNr = a;
00495             }
00496             Elements.prepend(neu);
00497             m_Doc->GroupCounter++;
00498         }
00499     }
00500     m_Doc->DoDrawing = true;
00501     m_Doc->scMW()->ScriptRunning = false;
00502     if (interactive)
00503         m_Doc->setLoading(false);
00504     qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
00505     if ((Elements.count() > 0) && (!ret) && (interactive))
00506     {
00507         if (flags & LoadSavePlugin::lfScripted)
00508         {
00509             bool loadF = m_Doc->isLoading();
00510             m_Doc->setLoading(false);
00511             m_Doc->changed();
00512             m_Doc->setLoading(loadF);
00513             for (int dre=0; dre<Elements.count(); ++dre)
00514             {
00515                 m_Doc->m_Selection->addItem(Elements.at(dre), true);
00516             }
00517             m_Doc->m_Selection->setGroupRect();
00518             m_Doc->view()->updatesOn(true);
00519             importCanceled = false;
00520         }
00521         else
00522         {
00523             m_Doc->DragP = true;
00524             m_Doc->DraggedElem = 0;
00525             m_Doc->DragElements.clear();
00526             for (int dre=0; dre<Elements.count(); ++dre)
00527             {
00528                 m_Doc->DragElements.append(Elements.at(dre)->ItemNr);
00529                 tmpSel->addItem(Elements.at(dre), true);
00530             }
00531             ScriXmlDoc *ss = new ScriXmlDoc();
00532             tmpSel->setGroupRect();
00533             //CB keep for reference conversion for now
00534             //Q3DragObject *dr = new Q3TextDrag(ss->WriteElem(m_Doc, m_Doc->view(), tmpSel), m_Doc->view()->viewport());
00535             QMimeData* md = new QMimeData();
00536             md->setText(ss->WriteElem(m_Doc, m_Doc->view(), tmpSel));
00537             QDrag* dr = new QDrag(m_Doc->view()->viewport());
00538             dr->setMimeData(md);
00539 #ifndef QT_WS_MAC
00540 // see #2196, #2526
00541             m_Doc->itemSelection_DeleteItem(tmpSel);
00542 #endif
00543 //          m_Doc->view()->resizeContents(qRound((maxSize.x() - minSize.x()) * m_Doc->view()->scale()), qRound((maxSize.y() - minSize.y()) * m_Doc->view()->scale()));
00544 //          m_Doc->view()->scrollBy(qRound((m_Doc->minCanvasCoordinate.x() - minSize.x()) * m_Doc->view()->scale()), qRound((m_Doc->minCanvasCoordinate.y() - minSize.y()) * m_Doc->view()->scale()));
00545             m_Doc->minCanvasCoordinate = minSize;
00546             m_Doc->maxCanvasCoordinate = maxSize;
00547             m_Doc->view()->adjustCanvas(qRound((maxSize.x() - minSize.x()) * m_Doc->view()->scale()), qRound((maxSize.y() - minSize.y()) * m_Doc->view()->scale()), 0, 0);
00548             m_Doc->view()->setCanvasOrigin(cOrigin.x(), cOrigin.y());
00549             m_Doc->view()->updatesOn(true);
00550             m_Doc->view()->updateCanvas();
00551             const QPixmap& dragCursor = loadIcon("DragPix.xpm");
00552             dr->setDragCursor(dragCursor, Qt::CopyAction);
00553             dr->setDragCursor(dragCursor, Qt::MoveAction);
00554             dr->setDragCursor(dragCursor, Qt::LinkAction);
00555             dr->exec();
00556             /* JG : incorrect, see the Qt Reference: "The function returns TRUE if the caller should 
00557             delete the original copy of the dragged data */
00558             /*importCanceled = dr->drag();
00559             if (!importCanceled)
00560             {
00561                 if (importedColors.count() != 0)
00562                 {
00563                     for (int cd = 0; cd < importedColors.count(); cd++)
00564                     {
00565                         m_Doc->PageColors.remove(importedColors[cd]);
00566                     }
00567                 }
00568             }*/
00569             delete ss;
00570             m_Doc->DragP = false;
00571             m_Doc->DraggedElem = 0;
00572             m_Doc->DragElements.clear();
00573         }
00574     }
00575     else
00576     {
00577         bool loadF = m_Doc->isLoading();
00578         m_Doc->setLoading(false);
00579         m_Doc->changed();
00580         m_Doc->reformPages();
00581         m_Doc->view()->updatesOn(true);
00582         m_Doc->setLoading(loadF);
00583     }
00584     return true;
00585 }
00586 
00587 QList<PageItem*> OODPlug::parseGroup(const QDomElement &e)
00588 {
00589     OODrawStyle oostyle;
00590     FPointArray ImgClip;
00591     QList<PageItem*> elements, cElements;
00592     double BaseX = m_Doc->currentPage()->xOffset();
00593     double BaseY = m_Doc->currentPage()->yOffset();
00594     storeObjectStyles(e);
00595     parseStyle(oostyle, e);
00596     QString drawID = e.attribute("draw:name");
00597     int zn = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, BaseX, BaseY, 1, 1, 0, CommonStrings::None, CommonStrings::None, true);
00598     PageItem *neu = m_Doc->Items->at(zn);
00599     for (QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling())
00600     {
00601         QDomElement b = n.toElement();
00602         if( b.isNull() )
00603             continue;
00604         QList<PageItem*> el = parseElement(b);
00605         for (int ec = 0; ec < el.count(); ++ec)
00606             cElements.append(el.at(ec));
00607     }
00608     if (cElements.count() < 2)
00609     {
00610         m_Doc->Items->takeAt(zn);
00611         delete neu;
00612         for (int a = 0; a < m_Doc->Items->count(); ++a)
00613         {
00614             m_Doc->Items->at(a)->ItemNr = a;
00615         }
00616         for (int gr = 0; gr < cElements.count(); ++gr)
00617         {
00618             elements.append(cElements.at(gr));
00619         }
00620     }
00621     else
00622     {
00623         double minx = 99999.9;
00624         double miny = 99999.9;
00625         double maxx = -99999.9;
00626         double maxy = -99999.9;
00627         elements.append(neu);
00628         for (int gr = 0; gr < cElements.count(); ++gr)
00629         {
00630             PageItem* currItem = cElements.at(gr);
00631             double lw = currItem->lineWidth() / 2.0;
00632             if (currItem->rotation() != 0)
00633             {
00634                 FPointArray pb;
00635                 pb.resize(0);
00636                 pb.addPoint(FPoint(currItem->xPos()-lw, currItem->yPos()-lw));
00637                 pb.addPoint(FPoint(currItem->width()+lw*2.0, -lw, currItem->xPos()-lw, currItem->yPos()-lw, currItem->rotation(), 1.0, 1.0));
00638                 pb.addPoint(FPoint(currItem->width()+lw*2.0, currItem->height()+lw*2.0, currItem->xPos()-lw, currItem->yPos()-lw, currItem->rotation(), 1.0, 1.0));
00639                 pb.addPoint(FPoint(-lw, currItem->height()+lw*2.0, currItem->xPos()-lw, currItem->yPos()-lw, currItem->rotation(), 1.0, 1.0));
00640                 for (uint pc = 0; pc < 4; ++pc)
00641                 {
00642                     minx = qMin(minx, pb.point(pc).x());
00643                     miny = qMin(miny, pb.point(pc).y());
00644                     maxx = qMax(maxx, pb.point(pc).x());
00645                     maxy = qMax(maxy, pb.point(pc).y());
00646                 }
00647             }
00648             else
00649             {
00650                 minx = qMin(minx, currItem->xPos()-lw);
00651                 miny = qMin(miny, currItem->yPos()-lw);
00652                 maxx = qMax(maxx, currItem->xPos()-lw + currItem->width()+lw*2.0);
00653                 maxy = qMax(maxy, currItem->yPos()-lw + currItem->height()+lw*2.0);
00654             }
00655         }
00656         double gx = minx;
00657         double gy = miny;
00658         double gw = maxx - minx;
00659         double gh = maxy - miny;
00660         neu->setXYPos(gx, gy);
00661         neu->setWidthHeight(gw, gh);
00662         if (ImgClip.size() != 0)
00663             neu->PoLine = ImgClip.copy();
00664         else
00665             neu->SetRectFrame();
00666         ImgClip.resize(0);
00667         neu->Clip = FlattenPath(neu->PoLine, neu->Segments);
00668         neu->Groups.push(m_Doc->GroupCounter);
00669         neu->isGroupControl = true;
00670         neu->groupsLastItem = cElements.at(cElements.count()-1);
00671         if( !e.attribute("id").isEmpty() )
00672             neu->setItemName(e.attribute("id"));
00673         else
00674             neu->setItemName( tr("Group%1").arg(neu->Groups.top()));
00675 //      neu->setFillTransparency(1 - gc->Opacity);
00676         for (int gr = 0; gr < cElements.count(); ++gr)
00677         {
00678             cElements.at(gr)->Groups.push(m_Doc->GroupCounter);
00679             elements.append(cElements.at(gr));
00680         }
00681         neu->setTextFlowMode(PageItem::TextFlowUsesFrameShape);
00682         m_Doc->GroupCounter++;
00683     }
00684     return elements;
00685 }
00686 
00687 QList<PageItem*> OODPlug::parseElement(const QDomElement &e)
00688 {
00689     QList<PageItem*> GElements;
00690     QString STag = e.tagName();
00691     if ( STag == "draw:g" )
00692     {
00693         GElements = parseGroup(e);
00694         return GElements;
00695     }
00696     if ( STag == "draw:rect" )
00697         GElements = parseRect(e);
00698     else if ( STag == "draw:circle" || STag == "draw:ellipse" )
00699         GElements = parseEllipse(e);
00700     else if ( STag == "draw:line" )
00701         GElements = parseLine(e);
00702     else if ( STag == "draw:polygon" )
00703         GElements = parsePolygon(e);
00704     else if ( STag == "draw:polyline" )
00705         GElements = parsePolyline(e);
00706     else if( STag == "draw:path" )
00707         GElements = parsePath(e);
00708     else if ( STag == "draw:text-box" )
00709         GElements = parseTextBox(e);
00710     else if ( STag == "draw:frame" )
00711         GElements = parseFrame(e);
00712     else if ( STag == "draw:connector" )
00713         GElements = parseConnector(e);
00714     else
00715     {
00716         // warn if unsupported feature are encountered
00717         unsupported = true;
00718         qDebug("Not supported yet: %s", STag.toLocal8Bit().data());
00719     }
00720     return GElements;
00721 }
00722 
00723 QList<PageItem*> OODPlug::parseRect(const QDomElement &e)
00724 {
00725     OODrawStyle style;
00726     QList<PageItem*> elements;
00727     double BaseX = m_Doc->currentPage()->xOffset();
00728     double BaseY = m_Doc->currentPage()->yOffset();
00729     double x = parseUnit(e.attribute("svg:x"));
00730     double y = parseUnit(e.attribute("svg:y")) ;
00731     double w = parseUnit(e.attribute("svg:width"));
00732     double h = parseUnit(e.attribute("svg:height"));
00733     double corner = parseUnit(e.attribute("draw:corner-radius"));
00734     storeObjectStyles(e);
00735     parseStyle(style, e);
00736     int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, BaseX+x, BaseY+y, w, h, style.strokeWidth, style.fillColor, style.strokeColor, true);
00737     PageItem* ite = m_Doc->Items->at(z);
00738     if (corner != 0)
00739     {
00740         ite->setCornerRadius(corner);
00741         ite->SetFrameRound();
00742         m_Doc->setRedrawBounding(ite);
00743     }
00744     ite = finishNodeParsing(e, ite, style);
00745     elements.append(ite);
00746     return elements;
00747 }
00748 
00749 QList<PageItem*> OODPlug::parseEllipse(const QDomElement &e)
00750 {
00751     OODrawStyle style;
00752     QList<PageItem*> elements;
00753     double BaseX = m_Doc->currentPage()->xOffset();
00754     double BaseY = m_Doc->currentPage()->yOffset();
00755     double x = parseUnit(e.attribute("svg:x"));
00756     double y = parseUnit(e.attribute("svg:y")) ;
00757     double w = parseUnit(e.attribute("svg:width"));
00758     double h = parseUnit(e.attribute("svg:height"));
00759     storeObjectStyles(e);
00760     parseStyle(style, e);
00761     int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, BaseX+x, BaseY+y, w, h, style.strokeWidth, style.fillColor, style.strokeColor, true);
00762     PageItem* ite = m_Doc->Items->at(z);
00763     ite = finishNodeParsing(e, ite, style);
00764     elements.append(ite);
00765     return elements;
00766 }
00767 
00768 QList<PageItem*> OODPlug::parseLine(const QDomElement &e)
00769 {
00770     OODrawStyle style;
00771     QList<PageItem*> elements;
00772     double BaseX = m_Doc->currentPage()->xOffset();
00773     double BaseY = m_Doc->currentPage()->yOffset();
00774     double x1 = e.attribute( "svg:x1" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:x1" ) );
00775     double y1 = e.attribute( "svg:y1" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:y1" ) );
00776     double x2 = e.attribute( "svg:x2" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:x2" ) );
00777     double y2 = e.attribute( "svg:y2" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:y2" ) );
00778     storeObjectStyles(e);
00779     parseStyle(style, e);
00780     int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, BaseX, BaseY, 10, 10, style.strokeWidth, CommonStrings::None, style.strokeColor, true);
00781     PageItem* ite = m_Doc->Items->at(z);
00782     ite->PoLine.resize(4);
00783     ite->PoLine.setPoint(0, FPoint(x1, y1));
00784     ite->PoLine.setPoint(1, FPoint(x1, y1));
00785     ite->PoLine.setPoint(2, FPoint(x2, y2));
00786     ite->PoLine.setPoint(3, FPoint(x2, y2));
00787     FPoint wh = getMaxClipF(&ite->PoLine);
00788