Rev 8405 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4430 | cbradney | 1 | /* |
2 | For general Scribus (>=1.3.2) copyright and licensing information please refer |
||
3 | to the COPYING file provided with the program. Following this notice may exist |
||
4 | a copyright and/or license notice that predates the release of Scribus 1.3.2 |
||
5 | for which a new license (GPL+exception) is in place. |
||
6 | */ |
||
766 | cbradney | 7 | #include <qwidget.h> |
8 | #include <qfile.h> |
||
9 | #include <qtextstream.h> |
||
10 | #include <qregexp.h> |
||
11 | #include <qcursor.h> |
||
12 | #include <qdragobject.h> |
||
13 | #include <qdir.h> |
||
14 | #include <qstring.h> |
||
3207 | craig | 15 | #include <qdom.h> |
766 | cbradney | 16 | #include <cmath> |
17 | |||
541 | fschmid | 18 | #include "oodrawimp.h" |
19 | #include "oodrawimp.moc" |
||
766 | cbradney | 20 | |
2688 | craig | 21 | #include "scconfig.h" |
22 | |||
5781 | cbradney | 23 | #include "scribuscore.h" |
766 | cbradney | 24 | #include "scribusdoc.h" |
25 | #include "pageitem.h" |
||
26 | #include "fpointarray.h" |
||
541 | fschmid | 27 | #include "customfdialog.h" |
4463 | cbradney | 28 | #include "commonstrings.h" |
541 | fschmid | 29 | #include "color.h" |
30 | #include "scribusXml.h" |
||
31 | #include "mpalette.h" |
||
2856 | cbradney | 32 | #include "prefsmanager.h" |
541 | fschmid | 33 | #include "prefsfile.h" |
34 | #include "prefscontext.h" |
||
35 | #include "prefstable.h" |
||
1578 | tsoots | 36 | #include "fileunzip.h" |
3934 | cbradney | 37 | #include "selection.h" |
544 | fschmid | 38 | #include "serializer.h" |
1436 | tsoots | 39 | #include "undomanager.h" |
1549 | subik | 40 | #include "pluginmanager.h" |
2529 | craig | 41 | #include "util.h" |
3207 | craig | 42 | #include "stylestack.h" |
3696 | craig | 43 | #include "scraction.h" |
44 | #include "menumanager.h" |
||
7478 | jghali | 45 | #include "sccolorengine.h" |
541 | fschmid | 46 | |
47 | using namespace std; |
||
48 | |||
3207 | craig | 49 | int oodrawimp_getPluginAPIVersion() |
541 | fschmid | 50 | { |
3207 | craig | 51 | return PLUGIN_API_VERSION; |
541 | fschmid | 52 | } |
53 | |||
3207 | craig | 54 | ScPlugin* oodrawimp_getPlugin() |
541 | fschmid | 55 | { |
3207 | craig | 56 | OODrawImportPlugin* plug = new OODrawImportPlugin(); |
57 | Q_CHECK_PTR(plug); |
||
58 | return plug; |
||
541 | fschmid | 59 | } |
60 | |||
3207 | craig | 61 | void oodrawimp_freePlugin(ScPlugin* plugin) |
541 | fschmid | 62 | { |
3207 | craig | 63 | OODrawImportPlugin* plug = dynamic_cast<OODrawImportPlugin*>(plugin); |
64 | Q_ASSERT(plug); |
||
65 | delete plug; |
||
541 | fschmid | 66 | } |
67 | |||
3207 | craig | 68 | OODrawImportPlugin::OODrawImportPlugin() : |
3696 | craig | 69 | LoadSavePlugin(), |
70 | importAction(new ScrAction(ScrAction::DLL, QIconSet(), "", QKeySequence(), this, "ImportOpenOfficeDraw")) |
||
1208 | cbradney | 71 | { |
3207 | craig | 72 | // Set action info in languageChange, so we only have to do |
3686 | craig | 73 | // it in one place. This includes registering file formats. |
3207 | craig | 74 | languageChange(); |
5243 | cbradney | 75 | } |
3696 | craig | 76 | |
5243 | cbradney | 77 | void OODrawImportPlugin::addToMainWindowMenu(ScribusMainWindow *mw) |
78 | { |
||
3696 | craig | 79 | // Then hook up the action |
80 | importAction->setEnabled(true); |
||
81 | connect( importAction, SIGNAL(activated()), SLOT(import()) ); |
||
5246 | cbradney | 82 | mw->scrMenuMgr->addMenuItem(importAction, "FileImport"); |
1208 | cbradney | 83 | } |
84 | |||
3686 | craig | 85 | OODrawImportPlugin::~OODrawImportPlugin() |
86 | { |
||
87 | unregisterAll(); |
||
3696 | craig | 88 | // note: importAction is automatically deleted by Qt |
3686 | craig | 89 | }; |
3207 | craig | 90 | |
91 | void OODrawImportPlugin::languageChange() |
||
1208 | cbradney | 92 | { |
6260 | fschmid | 93 | importAction->setMenuText( tr("Import &OpenOffice.org Draw...")); |
3686 | craig | 94 | // (Re)register file formats |
95 | unregisterAll(); |
||
96 | registerFormats(); |
||
1208 | cbradney | 97 | } |
98 | |||
3207 | craig | 99 | const QString OODrawImportPlugin::fullTrName() const |
1208 | cbradney | 100 | { |
3207 | craig | 101 | return QObject::tr("OpenOffice.org Draw Importer"); |
1208 | cbradney | 102 | } |
103 | |||
3207 | craig | 104 | const ScActionPlugin::AboutData* OODrawImportPlugin::getAboutData() const |
1208 | cbradney | 105 | { |
3241 | craig | 106 | AboutData* about = new AboutData; |
3344 | fschmid | 107 | about->authors = "Franz Schmid <franz@scribus.info>"; |
3540 | cbradney | 108 | about->shortDescription = tr("Imports OpenOffice.org Draw Files"); |
109 | about->description = tr("Imports most OpenOffice.org Draw files into the current document, converting their vector data into Scribus objects."); |
||
3344 | fschmid | 110 | about->license = "GPL"; |
3241 | craig | 111 | Q_CHECK_PTR(about); |
112 | return about; |
||
1208 | cbradney | 113 | } |
114 | |||
3241 | craig | 115 | void OODrawImportPlugin::deleteAboutData(const AboutData* about) const |
1208 | cbradney | 116 | { |
3241 | craig | 117 | Q_ASSERT(about); |
118 | delete about; |
||
1208 | cbradney | 119 | } |
120 | |||
3686 | craig | 121 | void OODrawImportPlugin::registerFormats() |
3487 | craig | 122 | { |
123 | QString odtName = tr("OpenDocument 1.0 Draw", "Import/export format name"); |
||
4024 | craig | 124 | FileFormat odtformat(this); |
3643 | craig | 125 | odtformat.trName = odtName; // Human readable name |
4024 | craig | 126 | odtformat.formatId = FORMATID_ODGIMPORT; |
4309 | craig | 127 | odtformat.filter = odtName + " (*.odg *.ODG)"; // QFileDialog filter |
3688 | craig | 128 | odtformat.nameMatch = QRegExp("\\.odg$", false); |
3686 | craig | 129 | odtformat.load = true; |
130 | odtformat.save = false; |
||
3643 | craig | 131 | odtformat.mimeTypes = QStringList("application/vnd.oasis.opendocument.graphics"); // MIME types |
132 | odtformat.priority = 64; // Priority |
||
3686 | craig | 133 | registerFormat(odtformat); |
134 | |||
3487 | craig | 135 | QString sxdName = tr("OpenOffice.org 1.x Draw", "Import/export format name"); |
4024 | craig | 136 | FileFormat sxdformat(this); |
3643 | craig | 137 | sxdformat.trName = sxdName; // Human readable name |
4024 | craig | 138 | sxdformat.formatId = FORMATID_SXDIMPORT; |
4309 | craig | 139 | sxdformat.filter = sxdName + " (*.sxd *.SXD)"; // QFileDialog filter |
3688 | craig | 140 | sxdformat.nameMatch = QRegExp("\\.sxd$", false); |
3686 | craig | 141 | sxdformat.load = true; |
142 | sxdformat.save = false; |
||
3643 | craig | 143 | sxdformat.mimeTypes = QStringList("application/vnd.sun.xml.draw"); // MIME types |
144 | sxdformat.priority = 64; // Priority |
||
3686 | craig | 145 | registerFormat(sxdformat); |
3487 | craig | 146 | } |
147 | |||
5642 | cbradney | 148 | bool OODrawImportPlugin::fileSupported(QIODevice* /* file */, const QString & fileName) const |
3487 | craig | 149 | { |
150 | // TODO: try to identify .sxd / .odt files |
||
151 | return true; |
||
152 | } |
||
153 | |||
5539 | mrdocs | 154 | bool OODrawImportPlugin::loadFile(const QString & fileName, const FileFormat &, int flags, int /*index*/) |
541 | fschmid | 155 | { |
3696 | craig | 156 | // For this plugin, right now "load" and "import" are the same thing |
5539 | mrdocs | 157 | return import(fileName, flags); |
3696 | craig | 158 | } |
159 | |||
5539 | mrdocs | 160 | bool OODrawImportPlugin::import(QString fileName, int flags) |
3696 | craig | 161 | { |
5539 | mrdocs | 162 | if (!checkFlags(flags)) |
163 | return false; |
||
3207 | craig | 164 | if (fileName.isEmpty()) |
541 | fschmid | 165 | { |
5539 | mrdocs | 166 | flags |= lfInteractive; |
2856 | cbradney | 167 | PrefsContext* prefs = PrefsManager::instance()->prefsFile->getPluginContext("OODrawImport"); |
541 | fschmid | 168 | QString wdir = prefs->get("wdir", "."); |
5781 | cbradney | 169 | CustomFDialog diaf(ScCore->primaryMainWindow(), wdir, QObject::tr("Open"), QObject::tr("OpenOffice.org Draw (*.sxd *.odg);;All Files (*)")); |
541 | fschmid | 170 | if (diaf.exec()) |
171 | { |
||
172 | fileName = diaf.selectedFile(); |
||
173 | prefs->set("wdir", fileName.left(fileName.findRev("/"))); |
||
174 | } |
||
175 | else |
||
3207 | craig | 176 | return true; |
541 | fschmid | 177 | } |
5781 | cbradney | 178 | m_Doc=ScCore->primaryMainWindow()->doc; |
179 | if (UndoManager::undoEnabled() && m_Doc) |
||
1439 | tsoots | 180 | { |
5781 | cbradney | 181 | UndoManager::instance()->beginTransaction(m_Doc->currentPage()->getUName(), |
5087 | subik | 182 | Um::IImageFrame, |
183 | Um::ImportOOoDraw, |
||
184 | fileName, Um::IImportOOoDraw); |
||
1439 | tsoots | 185 | } |
5781 | cbradney | 186 | else if (UndoManager::undoEnabled() && !m_Doc) |
1439 | tsoots | 187 | UndoManager::instance()->setUndoEnabled(false); |
5781 | cbradney | 188 | OODPlug dia(m_Doc); |
5539 | mrdocs | 189 | bool importDone = dia.import(fileName, flags); |
1436 | tsoots | 190 | if (UndoManager::undoEnabled()) |
191 | UndoManager::instance()->commit(); |
||
1439 | tsoots | 192 | else |
193 | UndoManager::instance()->setUndoEnabled(true); |
||
7795 | fschmid | 194 | if (dia.importCanceled) |
195 | { |
||
196 | if ((!importDone) || (dia.importFailed)) |
||
197 | QMessageBox::warning(ScCore->primaryMainWindow(), CommonStrings::trWarning, tr("The file could not be imported"), 1, 0, 0); |
||
198 | else if (dia.unsupported) |
||
199 | QMessageBox::warning(ScCore->primaryMainWindow(), CommonStrings::trWarning, tr("This file contains some unsupported features"), 1, 0, 0); |
||
200 | } |
||
4463 | cbradney | 201 | return importDone; |
541 | fschmid | 202 | } |
203 | |||
5781 | cbradney | 204 | OODPlug::OODPlug(ScribusDoc* doc) |
541 | fschmid | 205 | { |
5781 | cbradney | 206 | m_Doc=doc; |
7271 | jghali | 207 | unsupported = false; |
4463 | cbradney | 208 | interactive = false; |
7794 | fschmid | 209 | importFailed = false; |
7795 | fschmid | 210 | importCanceled = true; |
7991 | fschmid | 211 | importedColors.clear(); |
7580 | cbradney | 212 | tmpSel=new Selection(this, false); |
4463 | cbradney | 213 | } |
214 | |||
5539 | mrdocs | 215 | bool OODPlug::import( QString fileName, int flags ) |
4463 | cbradney | 216 | { |
217 | bool importDone = false; |
||
5539 | mrdocs | 218 | interactive = (flags & LoadSavePlugin::lfInteractive); |
550 | fschmid | 219 | QString f, f2, f3; |
4463 | cbradney | 220 | if ( !QFile::exists(fileName) ) |
221 | return false; |
||
541 | fschmid | 222 | m_styles.setAutoDelete( true ); |
1578 | tsoots | 223 | FileUnzip* fun = new FileUnzip(fileName); |
224 | stylePath = fun->getFile("styles.xml"); |
||
225 | contentPath = fun->getFile("content.xml"); |
||
226 | metaPath = fun->getFile("meta.xml"); |
||
227 | delete fun; |
||
541 | fschmid | 228 | if ((stylePath != NULL) && (contentPath != NULL)) |
229 | { |
||
230 | QString docname = fileName.right(fileName.length() - fileName.findRev("/") - 1); |
||
231 | docname = docname.left(docname.findRev(".")); |
||
232 | loadText(stylePath, &f); |
||
233 | if(!inpStyles.setContent(f)) |
||
4463 | cbradney | 234 | return false; |
541 | fschmid | 235 | loadText(contentPath, &f2); |
236 | if(!inpContents.setContent(f2)) |
||
4463 | cbradney | 237 | return false; |
541 | fschmid | 238 | QFile f1(stylePath); |
239 | f1.remove(); |
||
240 | QFile f2(contentPath); |
||
241 | f2.remove(); |
||
550 | fschmid | 242 | if (metaPath != NULL) |
243 | { |
||
244 | HaveMeta = true; |
||
245 | loadText(metaPath, &f3); |
||
246 | if(!inpMeta.setContent(f3)) |
||
247 | HaveMeta = false; |
||
248 | QFile f3(metaPath); |
||
249 | f3.remove(); |
||
250 | } |
||
251 | else |
||
252 | HaveMeta = false; |
||
541 | fschmid | 253 | } |
254 | else if ((stylePath == NULL) && (contentPath != NULL)) |
||
255 | { |
||
256 | QFile f2(contentPath); |
||
257 | f2.remove(); |
||
258 | } |
||
259 | else if ((stylePath != NULL) && (contentPath == NULL)) |
||
260 | { |
||
261 | QFile f1(stylePath); |
||
262 | f1.remove(); |
||
263 | } |
||
264 | QString CurDirP = QDir::currentDirPath(); |
||
265 | QFileInfo efp(fileName); |
||
266 | QDir::setCurrent(efp.dirPath()); |
||
5539 | mrdocs | 267 | importDone = convert(flags); |
541 | fschmid | 268 | QDir::setCurrent(CurDirP); |
4463 | cbradney | 269 | return importDone; |
541 | fschmid | 270 | } |
271 | |||
5539 | mrdocs | 272 | bool OODPlug::convert(int flags) |
541 | fschmid | 273 | { |
274 | bool ret = false; |
||
4590 | cbradney | 275 | bool isOODraw2 = false; |
276 | QDomNode drawPagePNode; |
||
544 | fschmid | 277 | int PageCounter = 0; |
8216 | jghali | 278 | QPtrList<PageItem> Elements; |
541 | fschmid | 279 | createStyleMap( inpStyles ); |
280 | QDomElement docElem = inpContents.documentElement(); |
||
281 | QDomNode automaticStyles = docElem.namedItem( "office:automatic-styles" ); |
||
282 | if( !automaticStyles.isNull() ) |
||
283 | insertStyles( automaticStyles.toElement() ); |
||
284 | QDomNode body = docElem.namedItem( "office:body" ); |
||
285 | QDomNode drawPage = body.namedItem( "draw:page" ); |
||
4590 | cbradney | 286 | if ( drawPage.isNull() ) |
4463 | cbradney | 287 | { |
288 | QDomNode offDraw = body.namedItem( "office:drawing" ); |
||
289 | drawPage = offDraw.namedItem( "draw:page" ); |
||
290 | if (drawPage.isNull()) |
||
291 | { |
||
5781 | cbradney | 292 | QMessageBox::warning( m_Doc->scMW(), CommonStrings::trWarning, tr("This document does not seem to be an OpenOffice Draw file.") ); |
4463 | cbradney | 293 | return false; |
294 | } |
||
295 | else |
||
296 | { |
||
4590 | cbradney | 297 | isOODraw2 = true; |
298 | drawPagePNode = body.namedItem( "office:drawing" ); |
||
4463 | cbradney | 299 | } |
300 | } |
||
4590 | cbradney | 301 | else |
302 | drawPagePNode = body; |
||
303 | StyleStack::Mode mode = isOODraw2 ? StyleStack::OODraw2x : StyleStack::OODraw1x; |
||
304 | m_styleStack.setMode( mode ); |
||
541 | fschmid | 305 | QDomElement dp = drawPage.toElement(); |
306 | QDomElement *master = m_styles[dp.attribute( "draw:master-page-name" )]; |
||
4590 | cbradney | 307 | QDomElement *style = NULL; |
308 | QDomElement properties; |
||
309 | if (isOODraw2) |
||
310 | { |
||
311 | style = m_styles[master->attribute( "style:page-layout-name" )]; |
||
312 | properties = style->namedItem( "style:page-layout-properties" ).toElement(); |
||
313 | } |
||
314 | else |
||
315 | { |
||
316 | style = m_styles[master->attribute( "style:page-master-name" )]; |
||
317 | properties = style->namedItem( "style:properties" ).toElement(); |
||
318 | } |
||
541 | fschmid | 319 | double width = !properties.attribute( "fo:page-width" ).isEmpty() ? parseUnit(properties.attribute( "fo:page-width" ) ) : 550.0; |
320 | double height = !properties.attribute( "fo:page-height" ).isEmpty() ? parseUnit(properties.attribute( "fo:page-height" ) ) : 841.0; |
||
5539 | mrdocs | 321 | if (!interactive || (flags & LoadSavePlugin::lfInsertPage)) |
5781 | cbradney | 322 | m_Doc->setPage(width, height, 0, 0, 0, 0, 0, 0, false, false); |
541 | fschmid | 323 | else |
324 | { |
||
5781 | cbradney | 325 | if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc)) |
541 | fschmid | 326 | { |
5798 | jghali | 327 | m_Doc=ScCore->primaryMainWindow()->doFileNew(width, height, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true); |
5781 | cbradney | 328 | ScCore->primaryMainWindow()->HaveNewDoc(); |
541 | fschmid | 329 | ret = true; |
330 | } |
||
331 | } |
||
3207 | craig | 332 | if ((ret) || (!interactive)) |
550 | fschmid | 333 | { |
334 | if (width > height) |
||
5781 | cbradney | 335 | m_Doc->PageOri = 1; |
550 | fschmid | 336 | else |
5781 | cbradney | 337 | m_Doc->PageOri = 0; |
5789 | cbradney | 338 | m_Doc->m_pageSize = "Custom"; |
550 | fschmid | 339 | QDomNode mpg; |
340 | QDomElement metaElem = inpMeta.documentElement(); |
||
341 | QDomElement mp = metaElem.namedItem( "office:meta" ).toElement(); |
||
342 | mpg = mp.namedItem( "dc:title" ); |
||
343 | if (!mpg.isNull()) |
||
5781 | cbradney | 344 | m_Doc->documentInfo.setTitle(QString::fromUtf8(mpg.toElement().text())); |
550 | fschmid | 345 | mpg = mp.namedItem( "meta:initial-creator" ); |
346 | if (!mpg.isNull()) |
||
5781 | cbradney | 347 | m_Doc->documentInfo.setAuthor(QString::fromUtf8(mpg.toElement().text())); |
550 | fschmid | 348 | mpg = mp.namedItem( "dc:description" ); |
349 | if (!mpg.isNull()) |
||
5781 | cbradney | 350 | m_Doc->documentInfo.setComments(QString::fromUtf8(mpg.toElement().text())); |
550 | fschmid | 351 | mpg = mp.namedItem( "dc:language" ); |
352 | if (!mpg.isNull()) |
||
5781 | cbradney | 353 | m_Doc->documentInfo.setLangInfo(QString::fromUtf8(mpg.toElement().text())); |
550 | fschmid | 354 | mpg = mp.namedItem( "meta:creation-date" ); |
355 | if (!mpg.isNull()) |
||
5781 | cbradney | 356 | m_Doc->documentInfo.setDate(QString::fromUtf8(mpg.toElement().text())); |
550 | fschmid | 357 | mpg = mp.namedItem( "dc:creator" ); |
358 | if (!mpg.isNull()) |
||
5781 | cbradney | 359 | m_Doc->documentInfo.setContrib(QString::fromUtf8(mpg.toElement().text())); |
550 | fschmid | 360 | mpg = mp.namedItem( "meta:keywords" ); |
361 | if (!mpg.isNull()) |
||
362 | { |
||
363 | QString Keys = ""; |
||
364 | for( QDomNode n = mpg.firstChild(); !n.isNull(); n = n.nextSibling() ) |
||
365 | { |
||
366 | Keys += QString::fromUtf8(n.toElement().text())+", "; |
||
367 | } |
||
368 | if (Keys.length() > 2) |
||
5781 | cbradney | 369 | m_Doc->documentInfo.setKeywords(Keys.left(Keys.length()-2)); |
550 | fschmid | 370 | } |
371 | } |
||
5781 | cbradney | 372 | FPoint minSize = m_Doc->minCanvasCoordinate; |
373 | FPoint maxSize = m_Doc->maxCanvasCoordinate; |
||
374 | m_Doc->view()->Deselect(); |
||
541 | fschmid | 375 | Elements.clear(); |
5781 | cbradney | 376 | m_Doc->setLoading(true); |
377 | m_Doc->DoDrawing = false; |
||
7452 | fschmid | 378 | m_Doc->view()->updatesOn(false); |
5781 | cbradney | 379 | m_Doc->scMW()->ScriptRunning = true; |
541 | fschmid | 380 | qApp->setOverrideCursor(QCursor(Qt::waitCursor), true); |
9297 | jghali | 381 | m_Doc->PageColors.ensureBlackAndWhite(); |
4590 | cbradney | 382 | for( QDomNode drawPag = drawPagePNode.firstChild(); !drawPag.isNull(); drawPag = drawPag.nextSibling() ) |
541 | fschmid | 383 | { |
384 | QDomElement dpg = drawPag.toElement(); |
||
3207 | craig | 385 | if (!interactive) |
4025 | cbradney | 386 | { |
5781 | cbradney | 387 | m_Doc->addPage(PageCounter); |
388 | m_Doc->view()->addPage(PageCounter); |
||
4025 | cbradney | 389 | } |
545 | fschmid | 390 | PageCounter++; |
541 | fschmid | 391 | m_styleStack.clear(); |
392 | fillStyleStack( dpg ); |
||
8216 | jghali | 393 | QPtrList<PageItem> el = parseGroup( dpg ); |
394 | for (uint ec = 0; ec < el.count(); ++ec) |
||
395 | Elements.append(el.at(ec)); |
||
7234 | fschmid | 396 | if ((interactive) && (PageCounter == 1)) |
397 | break; |
||
541 | fschmid | 398 | } |
7580 | cbradney | 399 | tmpSel->clear(); |
7691 | fschmid | 400 | // if ((Elements.count() > 1) && (interactive)) |
7794 | fschmid | 401 | if (Elements.count() == 0) |
7991 | fschmid | 402 | { |
7794 | fschmid | 403 | importFailed = true; |
7991 | fschmid | 404 | if (importedColors.count() != 0) |
405 | { |
||
406 | for (uint cd = 0; cd < importedColors.count(); cd++) |
||
407 | { |
||
408 | m_Doc->PageColors.remove(importedColors[cd]); |
||
409 | } |
||
410 | } |
||
411 | } |
||
7691 | fschmid | 412 | if (Elements.count() > 1) |
541 | fschmid | 413 | { |
7445 | fschmid | 414 | bool isGroup = true; |
415 | int firstElem = -1; |
||
416 | if (Elements.at(0)->Groups.count() != 0) |
||
417 | firstElem = Elements.at(0)->Groups.top(); |
||
418 | for (uint bx = 0; bx < Elements.count(); ++bx) |
||
541 | fschmid | 419 | { |
7445 | fschmid | 420 | PageItem* bxi = Elements.at(bx); |
421 | if (bxi->Groups.count() != 0) |
||
422 | { |
||
423 | if (bxi->Groups.top() != firstElem) |
||
424 | isGroup = false; |
||
425 | } |
||
426 | else |
||
427 | isGroup = false; |
||
541 | fschmid | 428 | } |
7445 | fschmid | 429 | if (!isGroup) |
430 | { |
||
7598 | fschmid | 431 | double minx = 99999.9; |
432 | double miny = 99999.9; |
||
433 | double maxx = -99999.9; |
||
434 | double maxy = -99999.9; |
||
435 | uint lowestItem = 999999; |
||
436 | uint highestItem = 0; |
||
7445 | fschmid | 437 | for (uint a = 0; a < Elements.count(); ++a) |
438 | { |
||
439 | Elements.at(a)->Groups.push(m_Doc->GroupCounter); |
||
7598 | fschmid | 440 | PageItem* currItem = Elements.at(a); |
441 | lowestItem = QMIN(lowestItem, currItem->ItemNr); |
||
442 | highestItem = QMAX(highestItem, currItem->ItemNr); |
||
443 | double lw = currItem->lineWidth() / 2.0; |
||
444 | if (currItem->rotation() != 0) |
||
445 | { |
||
446 | FPointArray pb; |
||
447 | pb.resize(0); |
||
448 | pb.addPoint(FPoint(currItem->xPos()-lw, currItem->yPos()-lw)); |
||
449 | pb.addPoint(FPoint(currItem->width()+lw*2.0, -lw, currItem->xPos()-lw, currItem->yPos()-lw, currItem->rotation(), 1.0, 1.0)); |
||
450 | 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)); |
||
451 | pb.addPoint(FPoint(-lw, currItem->height()+lw*2.0, currItem->xPos()-lw, currItem->yPos()-lw, currItem->rotation(), 1.0, 1.0)); |
||
452 | for (uint pc = 0; pc < 4; ++pc) |
||
453 | { |
||
454 | minx = QMIN(minx, pb.point(pc).x()); |
||
455 | miny = QMIN(miny, pb.point(pc).y()); |
||
456 | maxx = QMAX(maxx, pb.point(pc).x()); |
||
457 | maxy = QMAX(maxy, pb.point(pc).y()); |
||
458 | } |
||
459 | } |
||
460 | else |
||
461 | { |
||
462 | minx = QMIN(minx, currItem->xPos()-lw); |
||
463 | miny = QMIN(miny, currItem->yPos()-lw); |
||
464 | maxx = QMAX(maxx, currItem->xPos()-lw + currItem->width()+lw*2.0); |
||
465 | maxy = QMAX(maxy, currItem->yPos()-lw + currItem->height()+lw*2.0); |
||
466 | } |
||
7445 | fschmid | 467 | } |
7598 | fschmid | 468 | double gx = minx; |
469 | double gy = miny; |
||
470 | double gw = maxx - minx; |
||
471 | double gh = maxy - miny; |
||
472 | PageItem *high = m_Doc->Items->at(highestItem); |
||
473 | int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, gx, gy, gw, gh, 0, m_Doc->toolSettings.dBrush, m_Doc->toolSettings.dPen, true); |
||
474 | PageItem *neu = m_Doc->Items->take(z); |
||
475 | m_Doc->Items->insert(lowestItem, neu); |
||
476 | neu->Groups.push(m_Doc->GroupCounter); |
||
477 | neu->setItemName( tr("Group%1").arg(neu->Groups.top())); |
||
478 | neu->isGroupControl = true; |
||
479 | neu->groupsLastItem = high; |
||
7830 | fschmid | 480 | neu->setTextFlowMode(PageItem::TextFlowUsesFrameShape); |
7598 | fschmid | 481 | for (uint a = 0; a < m_Doc->Items->count(); ++a) |
482 | { |
||
483 | m_Doc->Items->at(a)->ItemNr = a; |
||
484 | } |
||
485 | Elements.prepend(neu); |
||
7445 | fschmid | 486 | m_Doc->GroupCounter++; |
487 | } |
||
541 | fschmid | 488 | } |
5781 | cbradney | 489 | m_Doc->DoDrawing = true; |
490 | m_Doc->scMW()->ScriptRunning = false; |
||
3207 | craig | 491 | if (interactive) |
5781 | cbradney | 492 | m_Doc->setLoading(false); |
541 | fschmid | 493 | qApp->setOverrideCursor(QCursor(Qt::arrowCursor), true); |
3207 | craig | 494 | if ((Elements.count() > 0) && (!ret) && (interactive)) |
541 | fschmid | 495 | { |
8262 | fschmid | 496 | if (flags & LoadSavePlugin::lfScripted) |
541 | fschmid | 497 | { |
8262 | fschmid | 498 | bool loadF = m_Doc->isLoading(); |
499 | m_Doc->setLoading(false); |
||
500 | m_Doc->changed(); |
||
501 | m_Doc->setLoading(loadF); |
||
502 | for (uint dre=0; dre<Elements.count(); ++dre) |
||
503 | { |
||
504 | m_Doc->m_Selection->addItem(Elements.at(dre), true); |
||
505 | } |
||
506 | m_Doc->m_Selection->setGroupRect(); |
||
507 | m_Doc->view()->updatesOn(true); |
||
508 | importCanceled = false; |
||
541 | fschmid | 509 | } |
8262 | fschmid | 510 | else |
511 | { |
||
512 | m_Doc->DragP = true; |
||
513 | m_Doc->DraggedElem = 0; |
||
514 | m_Doc->DragElements.clear(); |
||
515 | for (uint dre=0; dre<Elements.count(); ++dre) |
||
516 | { |
||
517 | m_Doc->DragElements.append(Elements.at(dre)->ItemNr); |
||
518 | tmpSel->addItem(Elements.at(dre), true); |
||
519 | } |
||
520 | ScriXmlDoc *ss = new ScriXmlDoc(); |
||
521 | tmpSel->setGroupRect(); |
||
522 | QDragObject *dr = new QTextDrag(ss->WriteElem(m_Doc, m_Doc->view(), tmpSel), m_Doc->view()->viewport()); |
||
4302 | avox | 523 | #ifndef QT_MAC |
524 | // see #2196, #2526 |
||
8262 | fschmid | 525 | m_Doc->itemSelection_DeleteItem(tmpSel); |
4302 | avox | 526 | #endif |
8262 | fschmid | 527 | m_Doc->view()->resizeContents(qRound((maxSize.x() - minSize.x()) * m_Doc->view()->scale()), qRound((maxSize.y() - minSize.y()) * m_Doc->view()->scale())); |
528 | 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())); |
||
529 | m_Doc->minCanvasCoordinate = minSize; |
||
530 | m_Doc->maxCanvasCoordinate = maxSize; |
||
531 | m_Doc->view()->updatesOn(true); |
||
532 | dr->setPixmap(loadIcon("DragPix.xpm")); |
||
9297 | jghali | 533 | dr->drag(); |
534 | /*importCanceled = dr->drag(); |
||
8262 | fschmid | 535 | if (!importCanceled) |
7991 | fschmid | 536 | { |
8262 | fschmid | 537 | if (importedColors.count() != 0) |
7991 | fschmid | 538 | { |
8262 | fschmid | 539 | for (uint cd = 0; cd < importedColors.count(); cd++) |
540 | { |
||
541 | m_Doc->PageColors.remove(importedColors[cd]); |
||
542 | } |
||
7991 | fschmid | 543 | } |
9297 | jghali | 544 | }*/ |
8262 | fschmid | 545 | delete ss; |
546 | m_Doc->DragP = false; |
||
547 | m_Doc->DraggedElem = 0; |
||
548 | m_Doc->DragElements.clear(); |
||
7991 | fschmid | 549 | } |
541 | fschmid | 550 | } |
551 | else |
||
552 | { |
||
7351 | fschmid | 553 | bool loadF = m_Doc->isLoading(); |
554 | m_Doc->setLoading(false); |
||
5781 | cbradney | 555 | m_Doc->changed(); |
6556 | fschmid | 556 | m_Doc->reformPages(); |
7452 | fschmid | 557 | m_Doc->view()->updatesOn(true); |
7351 | fschmid | 558 | m_Doc->setLoading(loadF); |
541 | fschmid | 559 | } |
4463 | cbradney | 560 | return true; |
541 | fschmid | 561 | } |
562 | |||
991 | fschmid | 563 | QPtrList<PageItem> OODPlug::parseGroup(const QDomElement &e) |
541 | fschmid | 564 | { |
8216 | jghali | 565 | OODrawStyle oostyle; |
541 | fschmid | 566 | FPointArray ImgClip; |
8216 | jghali | 567 | QPtrList<PageItem> elements, cElements; |
5781 | cbradney | 568 | double BaseX = m_Doc->currentPage()->xOffset(); |
569 | double BaseY = m_Doc->currentPage()->yOffset(); |
||
8216 | jghali | 570 | storeObjectStyles(e); |
571 | parseStyle(oostyle, e); |
||
572 | QString drawID = e.attribute("draw:name"); |
||
573 | int zn = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, BaseX, BaseY, 1, 1, 0, CommonStrings::None, CommonStrings::None, true); |
||
574 | PageItem *neu = m_Doc->Items->at(zn); |
||
541 | fschmid | 575 | for (QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) |
576 | { |
||
577 | QDomElement b = n.toElement(); |
||
578 | if( b.isNull() ) |
||
579 | continue; |
||
8216 | jghali | 580 | QPtrList<PageItem> el = parseElement(b); |
581 | for (uint ec = 0; ec < el.count(); ++ec) |
||
582 | cElements.append(el.at(ec)); |
||
583 | } |
||
584 | if (cElements.count() < 2) |
||
585 | { |
||
586 | m_Doc->Items->take(zn); |
||
587 | delete neu; |
||
588 | for (uint a = 0; a < m_Doc->Items->count(); ++a) |
||
541 | fschmid | 589 | { |
8216 | jghali | 590 | m_Doc->Items->at(a)->ItemNr = a; |
541 | fschmid | 591 | } |
8216 | jghali | 592 | for (uint gr = 0; gr < cElements.count(); ++gr) |
541 | fschmid | 593 | { |
8216 | jghali | 594 | elements.append(cElements.at(gr)); |
541 | fschmid | 595 | } |
8216 | jghali | 596 | } |
597 | else |
||
598 | { |
||
599 | double minx = 99999.9; |
||
600 | double miny = 99999.9; |
||
601 | double maxx = -99999.9; |
||
602 | double maxy = -99999.9; |
||
603 | elements.append(neu); |
||
604 | for (uint gr = 0; gr < cElements.count(); ++gr) |
||
541 | fschmid | 605 | { |
8216 | jghali | 606 | PageItem* currItem = cElements.at(gr); |
607 | double lw = currItem->lineWidth() / 2.0; |
||
608 | if (currItem->rotation() != 0) |
||
548 | fschmid | 609 | { |
8216 | jghali | 610 | FPointArray pb; |
611 | pb.resize(0); |
||
612 | pb.addPoint(FPoint(currItem->xPos()-lw, currItem->yPos()-lw)); |
||
613 | pb.addPoint(FPoint(currItem->width()+lw*2.0, -lw, currItem->xPos()-lw, currItem->yPos()-lw, currItem->rotation(), 1.0, 1.0)); |
||
614 | 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)); |
||
615 | pb.addPoint(FPoint(-lw, currItem->height()+lw*2.0, currItem->xPos()-lw, currItem->yPos()-lw, currItem->rotation(), 1.0, 1.0)); |
||
616 | for (uint pc = 0; pc < 4; ++pc) |
||
7640 | fschmid | 617 | { |
8216 | jghali | 618 | minx = QMIN(minx, pb.point(pc).x()); |
619 | miny = QMIN(miny, pb.point(pc).y()); |
||
620 | maxx = QMAX(maxx, pb.point(pc).x()); |
||
621 | maxy = QMAX(maxy, pb.point(pc).y()); |
||
7640 | fschmid | 622 | } |
7598 | fschmid | 623 | } |
624 | else |
||
625 | { |
||
8216 | jghali | 626 | minx = QMIN(minx, currItem->xPos()-lw); |
627 | miny = QMIN(miny, currItem->yPos()-lw); |
||
628 | maxx = QMAX(maxx, currItem->xPos()-lw + currItem->width()+lw*2.0); |
||
629 | maxy = QMAX(maxy, currItem->yPos()-lw + currItem->height()+lw*2.0); |
||
7598 | fschmid | 630 | } |
545 | fschmid | 631 | } |
8216 | jghali | 632 | double gx = minx; |
633 | double gy = miny; |
||
634 | double gw = maxx - minx; |
||
635 | double gh = maxy - miny; |
||
636 | neu->setXYPos(gx, gy); |
||
637 | neu->setWidthHeight(gw, gh); |
||
638 | if (ImgClip.size() != 0) |
||
639 | neu->PoLine = ImgClip.copy(); |
||
640 | else |
||
641 | neu->SetRectFrame(); |
||
642 | ImgClip.resize(0); |
||
643 | neu->Clip = FlattenPath(neu->PoLine, neu->Segments); |
||
644 | neu->Groups.push(m_Doc->GroupCounter); |
||
645 | neu->isGroupControl = true; |
||
646 | neu->groupsLastItem = cElements.at(cElements.count()-1); |
||
647 | if( !e.attribute("id").isEmpty() ) |
||
648 | neu->setItemName(e.attribute("id")); |
||
649 | else |
||
650 | neu->setItemName( tr("Group%1").arg(neu->Groups.top())); |
||
651 | // neu->setFillTransparency(1 - gc->Opacity); |
||
652 | for (uint gr = 0; gr < cElements.count(); ++gr) |
||
545 | fschmid | 653 | { |
8216 | jghali | 654 | cElements.at(gr)->Groups.push(m_Doc->GroupCounter); |
655 | elements.append(cElements.at(gr)); |
||
541 | fschmid | 656 | } |
8216 | jghali | 657 | neu->setTextFlowMode(PageItem::TextFlowUsesFrameShape); |
658 | m_Doc->GroupCounter++; |
||
659 | } |
||
660 | return elements; |
||
661 | } |
||
662 | |||
663 | QPtrList<PageItem> OODPlug::parseElement(const QDomElement &e) |
||
664 | { |
||
665 | QPtrList<PageItem> GElements; |
||
666 | QString STag = e.tagName(); |
||
667 | if ( STag == "draw:g" ) |
||
668 | { |
||
669 | GElements = parseGroup(e); |
||
670 | return GElements; |
||
671 | } |
||
672 | if ( STag == "draw:rect" ) |
||
673 | GElements = parseRect(e); |
||
674 | else if ( STag == "draw:circle" || STag == "draw:ellipse" ) |
||
675 | GElements = parseEllipse(e); |
||
676 | else if ( STag == "draw:line" ) |
||
677 | GElements = parseLine(e); |
||
678 | else if ( STag == "draw:polygon" ) |
||
679 | GElements = parsePolygon(e); |
||
680 | else if ( STag == "draw:polyline" ) |
||
681 | GElements = parsePolyline(e); |
||
682 | else if( STag == "draw:path" ) |
||
683 | GElements = parsePath(e); |
||
684 | else if ( STag == "draw:text-box" ) |
||
685 | GElements = parseTextBox(e); |
||
686 | else if ( STag == "draw:frame" ) |
||
687 | GElements = parseFrame(e); |
||
8222 | jghali | 688 | else if ( STag == "draw:connector" ) |
689 | GElements = parseConnector(e); |
||
8216 | jghali | 690 | else |
691 | { |
||
692 | // warn if unsupported feature are encountered |
||
693 | unsupported = true; |
||
694 | qDebug("Not supported yet: %s", STag.local8Bit().data()); |
||
695 | } |
||
696 | return GElements; |
||
697 | } |
||
698 | |||
699 | QPtrList<PageItem> OODPlug::parseRect(const QDomElement &e) |
||
700 | { |
||
701 | OODrawStyle style; |
||
702 | QPtrList<PageItem> elements; |
||
703 | double BaseX = m_Doc->currentPage()->xOffset(); |
||
704 | double BaseY = m_Doc->currentPage()->yOffset(); |
||
705 | double x = parseUnit(e.attribute("svg:x")); |
||
706 | double y = parseUnit(e.attribute("svg:y")) ; |
||
707 | double w = parseUnit(e.attribute("svg:width")); |
||
708 | double h = parseUnit(e.attribute("svg:height")); |
||
709 | double corner = parseUnit(e.attribute("draw:corner-radius")); |
||
710 | storeObjectStyles(e); |
||
711 | parseStyle(style, e); |
||
712 | int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, BaseX+x, BaseY+y, w, h, style.strokeWidth, style.fillColor, style.strokeColor, true); |
||
713 | PageItem* ite = m_Doc->Items->at(z); |
||
714 | if (corner != 0) |
||
715 | { |
||
716 | ite->setCornerRadius(corner); |
||
717 | ite->SetFrameRound(); |
||
718 | m_Doc->setRedrawBounding(ite); |
||
719 | } |
||
8278 | jghali | 720 | ite = finishNodeParsing(e, ite, style); |
8216 | jghali | 721 | elements.append(ite); |
722 | return elements; |
||
723 | } |
||
724 | |||
725 | QPtrList<PageItem> OODPlug::parseEllipse(const QDomElement &e) |
||
726 | { |
||
727 | OODrawStyle style; |
||
728 | QPtrList<PageItem> elements; |
||
729 | double BaseX = m_Doc->currentPage()->xOffset(); |
||
730 | double BaseY = m_Doc->currentPage()->yOffset(); |
||
731 | double x = parseUnit(e.attribute("svg:x")); |
||
732 | double y = parseUnit(e.attribute("svg:y")) ; |
||
733 | double w = parseUnit(e.attribute("svg:width")); |
||
734 | double h = parseUnit(e.attribute("svg:height")); |
||
735 | storeObjectStyles(e); |
||
736 | parseStyle(style, e); |
||
737 | int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, BaseX+x, BaseY+y, w, h, style.strokeWidth, style.fillColor, style.strokeColor, true); |
||
738 | PageItem* ite = m_Doc->Items->at(z); |
||
8278 | jghali | 739 | ite = finishNodeParsing(e, ite, style); |
8216 | jghali | 740 | elements.append(ite); |
741 | return elements; |
||
742 | } |
||
743 | |||
744 | QPtrList<PageItem> OODPlug::parseLine(const QDomElement &e) |
||
745 | { |
||
746 | OODrawStyle style; |
||
747 | QPtrList<PageItem> elements; |
||
748 | double BaseX = m_Doc->currentPage()->xOffset(); |
||
749 | double BaseY = m_Doc->currentPage()->yOffset(); |
||
750 | double x1 = e.attribute( "svg:x1" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:x1" ) ); |
||
751 | double y1 = e.attribute( "svg:y1" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:y1" ) ); |
||
752 | double x2 = e.attribute( "svg:x2" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:x2" ) ); |
||
753 | double y2 = e.attribute( "svg:y2" ).isEmpty() ? 0.0 : parseUnit( e.attribute( "svg:y2" ) ); |
||
754 | storeObjectStyles(e); |
||
755 | parseStyle(style, e); |
||
756 | int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, BaseX, BaseY, 10, 10, style.strokeWidth, CommonStrings::None, style.strokeColor, true); |
||
757 | PageItem* ite = m_Doc->Items->at(z); |
||
758 | ite->PoLine.resize(4); |
||
759 | ite->PoLine.setPoint(0, FPoint(x1, y1)); |
||
760 | ite->PoLine.setPoint(1, FPoint(x1, y1)); |
||
761 | ite->PoLine.setPoint(2, FPoint(x2, y2)); |
||
762 | ite->PoLine.setPoint(3, FPoint(x2, y2)); |
||
763 | FPoint wh = getMaxClipF(&ite->PoLine); |
||
764 | ite->setWidthHeight(wh.x(), wh.y()); |
||
765 | ite->ClipEdited = true; |
||
766 | ite->FrameType = 3; |
||
767 | if (!e.hasAttribute("draw:transform")) |
||
768 | { |
||
769 | ite->Clip = FlattenPath(ite->PoLine, ite->Segments); |
||
770 | m_Doc->AdjustItemSize(ite); |
||
771 | } |
||
8278 | jghali | 772 | ite = finishNodeParsing(e, ite, style); |
8216 | jghali | 773 | elements.append(ite); |
774 | return elements; |
||
775 | } |
||
776 | |||
777 | QPtrList<PageItem> OODPlug::parsePolygon(const QDomElement &e) |
||
778 | { |
||
779 | OODrawStyle style; |
||
780 | QPtrList<PageItem> elements; |
||
781 | double BaseX = m_Doc->currentPage()->xOffset(); |
||
782 | double BaseY = m_Doc->currentPage()->yOffset(); |
||
783 | storeObjectStyles(e); |
||
784 | parseStyle(style, e); |
||
785 | int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, BaseX, BaseY, 10, 10, style.strokeWidth, style.fillColor, style.strokeColor, true); |
||
786 | PageItem* ite = m_Doc->Items->at(z); |
||
787 | ite->PoLine.resize(0); |
||
788 | appendPoints(&ite->PoLine, e); |
||
789 | FPoint wh = getMaxClipF(&ite->PoLine); |
||
790 | ite->setWidthHeight(wh.x(), wh.y()); |
||
791 | ite->ClipEdited = true; |
||
792 | ite->FrameType = 3; |
||
793 | if (!e.hasAttribute("draw:transform")) |
||
794 | { |
||
795 | ite->Clip = FlattenPath(ite->PoLine, ite->Segments); |
||
796 | m_Doc->AdjustItemSize(ite); |
||
797 | } |
||
8278 | jghali | 798 | ite = finishNodeParsing(e, ite, style); |
8216 | jghali | 799 | elements.append(ite); |
800 | return elements; |
||
801 | } |
||
802 | |||
803 | QPtrList<PageItem> OODPlug::parsePolyline(const QDomElement &e) |
||
804 | { |
||
805 | OODrawStyle style; |
||
806 | QPtrList<PageItem> elements; |
||
807 | double BaseX = m_Doc->currentPage()->xOffset(); |
||
808 | double BaseY = m_Doc->currentPage()->yOffset(); |
||
809 | storeObjectStyles(e); |
||
810 | parseStyle(style, e); |
||
811 | int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, BaseX, BaseY, 10, 10, style.strokeWidth, CommonStrings::None, style.strokeColor, true); |
||
812 | PageItem* ite = m_Doc->Items->at(z); |
||
813 | ite->PoLine.resize(0); |
||
814 | appendPoints(&ite->PoLine, e); |
||
815 | FPoint wh = getMaxClipF(&ite->PoLine); |
||
816 | ite->setWidthHeight(wh.x(), wh.y()); |
||
817 | ite->ClipEdited = true; |
||
818 | ite->FrameType = 3; |
||
819 | if (!e.hasAttribute("draw:transform")) |
||
820 | { |
||
821 | ite->Clip = FlattenPath(ite->PoLine, ite->Segments); |
||
822 | m_Doc->AdjustItemSize(ite); |
||
823 | } |
||
8278 | jghali | 824 | ite = finishNodeParsing(e, ite, style); |
8216 | jghali | 825 | elements.append(ite); |
826 | return elements; |
||
827 | } |
||
828 | |||
829 | QPtrList<PageItem> OODPlug::parsePath(const QDomElement &e) |
||
830 | { |
||
831 | OODrawStyle style; |
||
832 | FPointArray pArray; |
||
833 | QPtrList<PageItem> elements; |
||
834 | double BaseX = m_Doc->currentPage()->xOffset(); |
||
835 | double BaseY = m_Doc->currentPage()->yOffset(); |
||
836 | storeObjectStyles(e); |
||
837 | parseStyle(style, e); |
||
838 | PageItem::ItemType itype = parseSVG(e.attribute("svg:d"), &pArray) ? PageItem::PolyLine : PageItem::Polygon; |
||
839 | int z = m_Doc->itemAdd(itype, PageItem::Unspecified, BaseX, BaseY, 10, 10, style.strokeWidth, style.fillColor, style.strokeColor, true); |
||
840 | PageItem* ite = m_Doc->Items->at(z); |
||
841 | ite->PoLine.resize(0); |
||
842 | ite->PoLine = pArray; |
||
843 | if (ite->PoLine.size() < 4) |
||
844 | { |
||
845 | // m_Doc->m_Selection->addItem(ite); |
||
846 | tmpSel->addItem(ite); |
||
847 | // m_Doc->itemSelection_DeleteItem(); |
||
848 | m_Doc->itemSelection_DeleteItem(tmpSel); |
||
849 | } |
||
850 | else |
||
851 | { |
||
852 | double x = parseUnit(e.attribute("svg:x")); |
||
853 | double y = parseUnit(e.attribute("svg:y")) ; |
||
854 | double w = parseUnit(e.attribute("svg:width")); |
||
855 | double h = parseUnit(e.attribute("svg:height")); |
||
856 | double vx = 0; |
||
857 | double vy = 0; |
||
858 | double vw = 1; |
||
859 | double vh = 1; |
||
860 | parseViewBox(e, &vx, &vy, &vw, &vh); |
||
861 | QWMatrix mat; |
||
862 | mat.translate(x, y); |
||
863 | mat.scale(w / vw, h / vh); |
||
864 | ite->PoLine.map(mat); |
||
865 | FPoint wh = getMaxClipF(&ite->PoLine); |
||
866 | ite->setWidthHeight(wh.x(), wh.y()); |
||
867 | ite->ClipEdited = true; |
||
868 | ite->FrameType = 3; |
||
869 | if (!e.hasAttribute("draw:transform")) |
||
544 | fschmid | 870 | { |
8216 | jghali | 871 | ite->Clip = FlattenPath(ite->PoLine, ite->Segments); |
872 | m_Doc->AdjustItemSize(ite); |
||
544 | fschmid | 873 | } |
8278 | jghali | 874 | ite = finishNodeParsing(e, ite, style); |
8216 | jghali | 875 | elements.append(ite); |
876 | } |
||
877 | return elements; |
||
878 | } |
||
879 | |||
880 | QPtrList<PageItem> OODPlug::parseTextBox(const QDomElement &e) |
||
881 | { |
||
882 | OODrawStyle style; |
||
883 | QPtrList<PageItem> elements; |
||
884 | double BaseX = m_Doc->currentPage()->xOffset(); |
||
885 | double BaseY = m_Doc->currentPage()->yOffset(); |
||
886 | double x = parseUnit(e.attribute("svg:x")); |
||
887 | double y = parseUnit(e.attribute("svg:y")) ; |
||
888 | double w = parseUnit(e.attribute("svg:width")); |
||
889 | double h = parseUnit(e.attribute("svg:height")); |
||
890 | storeObjectStyles(e); |
||
891 | parseStyle(style, e); |
||
892 | int z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, BaseX+x, BaseY+y, w, h+(h*0.1), style.strokeWidth, CommonStrings::None, style.strokeColor, true); |
||
893 | PageItem* ite = m_Doc->Items->at(z); |
||
894 | ite->setFillColor(style.fillColor); |
||
895 | ite->setLineColor(style.strokeColor); |
||
8278 | jghali | 896 | ite = finishNodeParsing(e, ite, style); |
8216 | jghali | 897 | elements.append(ite); |
898 | return elements; |
||
899 | } |
||
900 | |||
901 | QPtrList<PageItem> OODPlug::parseFrame(const QDomElement &e) |
||
902 | { |
||
903 | OODrawStyle oostyle; |
||
904 | QPtrList<PageItem> elements; |
||
905 | QString drawID = e.attribute("draw:name"); |
||
906 | double BaseX = m_Doc->currentPage()->xOffset(); |
||
907 | double BaseY = m_Doc->currentPage()->yOffset(); |
||
908 | double x = parseUnit(e.attribute("svg:x")); |
||
909 | double y = parseUnit(e.attribute("svg:y")) ; |
||
910 | double w = parseUnit(e.attribute("svg:width")); |
||
911 | double h = parseUnit(e.attribute("svg:height")); |
||
912 | storeObjectStyles(e); |
||
913 | parseStyle(oostyle, e); |
||
914 | QDomNode n = e.firstChild(); |
||
915 | QString STag2 = n.toElement().tagName(); |
||
916 | if ( STag2 == "draw:text-box" ) |
||
917 | { |
||
918 | int z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, BaseX+x, BaseY+y, w, h+(h*0.1), oostyle.strokeWidth, CommonStrings::None, oostyle.strokeColor, true); |
||
919 | PageItem* ite = m_Doc->Items->at(z); |
||
920 | ite->setTextToFrameDist(0.0, 0.0, 0.0, 0.0); |
||
921 | ite->setFillTransparency(oostyle.fillTrans); |
||
922 | ite->setLineTransparency(oostyle.strokeTrans); |
||
923 | ite->setTextFlowMode(PageItem::TextFlowUsesFrameShape); |
||
924 | if (!drawID.isEmpty()) |
||
925 | ite->setItemName(drawID); |
||
8387 | jghali | 926 | ite = parseTextP(n.toElement(), ite); |
8216 | jghali | 927 | elements.append(ite); |
928 | } |
||
929 | return elements; |
||
930 | } |
||
931 | |||
8222 | jghali | 932 | QPtrList<PageItem> OODPlug::parseConnector(const QDomElement &e) |
933 | { |
||
934 | QPtrList<PageItem> elements; |
||
935 | if (e.hasAttribute("svg:x1") && e.hasAttribute("svg:x2") && e.hasAttribute("svg:y1") && e.hasAttribute("svg:y2")) |
||
936 | { |
||
937 | elements = parseLine(e); |
||
938 | } |
||
939 | else |
||
940 | { |
||
941 | unsupported = true; |
||
942 | qDebug("an unsupported form of connector was found"); |
||
943 | } |
||
944 | return elements; |
||
945 | } |
||
946 | |||
8216 | jghali | 947 | void OODPlug::parseStyle(OODrawStyle& oostyle, const QDomElement &e) |
948 | { |
||
949 | oostyle.haveGradient = false; |
||
950 | oostyle.gradient.clearStops(); |
||
951 | if( m_styleStack.hasAttribute("draw:stroke") ) |
||
952 | { |
||
953 | if( m_styleStack.attribute( "draw:stroke" ) == "none" ) |
||
954 | oostyle.strokeWidth = 0.0; |
||
955 | else |
||
544 | fschmid | 956 | { |
8216 | jghali | 957 | if( m_styleStack.hasAttribute("svg:stroke-width")) |
548 | fschmid | 958 | { |
8216 | jghali | 959 | oostyle.strokeWidth = parseUnit(m_styleStack.attribute("svg:stroke-width")); |
960 | if (oostyle.strokeWidth == 0) |
||
961 | oostyle.strokeWidth = 1; |
||
548 | fschmid | 962 | } |
8216 | jghali | 963 | if( m_styleStack.hasAttribute("svg:stroke-color")) |
964 | oostyle.strokeColor = parseColor(m_styleStack.attribute("svg:stroke-color")); |
||
965 | if( m_styleStack.hasAttribute( "svg:stroke-opacity" ) ) |
||
966 | oostyle.strokeTrans = m_styleStack.attribute( "svg:stroke-opacity" ).remove( '%' ).toDouble() / 100.0; |
||
967 | if( m_styleStack.attribute( "draw:stroke" ) == "dash" ) |
||
548 | fschmid | 968 | { |
8216 | jghali | 969 | QString style = m_styleStack.attribute( "draw:stroke-dash" ); |
970 | if( style == "Ultrafine Dashed") |
||
971 | oostyle.dashes << 1.4 << 1.4; |
||
972 | else if( style == "Fine Dashed" ) |
||
973 | oostyle.dashes << 14.4 << 14.4; |
||
974 | else if( style == "Fine Dotted") |
||
975 | oostyle.dashes << 13 << 13; |
||
976 | else if( style == "Ultrafine 2 Dots 3 Dashes") |
||
977 | oostyle.dashes << 1.45 << 3.6 << 1.45 << 3.6 << 7.2 << 3.6 << 7.2 << 3.6 << 7.2 << 3.6; |
||
978 | else if( style == "Line with Fine Dots") |
||
548 | fschmid | 979 | { |
8216 | jghali | 980 | oostyle.dashes << 56.9 << 4.31; |
981 | for (int dd = 0; dd < 10; ++ dd) |
||
982 | { |
||
983 | oostyle.dashes << 8.6 << 4.31; |
||
984 | } |
||
548 | fschmid | 985 | } |
8216 | jghali | 986 | else if( style == "2 Dots 1 Dash" ) |
987 | oostyle.dashes << 2.8 << 5.75 << 2.8 << 5.75 << 5.75 << 5.75; |
||
544 | fschmid | 988 | } |
989 | } |
||
8216 | jghali | 990 | } |
991 | if( m_styleStack.hasAttribute( "draw:fill" ) ) |
||
992 | { |
||
993 | QString fill = m_styleStack.attribute( "draw:fill" ); |
||
994 | if( fill == "solid" ) |
||
544 | fschmid | 995 | { |
8216 | jghali | 996 | if( m_styleStack.hasAttribute( "draw:fill-color" ) ) |
997 | oostyle.fillColor = parseColor( m_styleStack.attribute("draw:fill-color")); |
||
998 | if( m_styleStack.hasAttribute( "draw:transparency" ) ) |
||
999 | oostyle.fillTrans = m_styleStack.attribute( "draw:transparency" ).remove( '%' ).toDouble() / 100.0; |
||
592 | fschmid | 1000 | } |
8216 | jghali | 1001 | else if( fill == "gradient" ) |
7293 | fschmid | 1002 | { |
8216 | jghali | 1003 | oostyle.haveGradient = true; |
1004 | oostyle.gradientAngle = 0; |
||
1005 | oostyle.gradient.clearStops(); |
||
1006 | oostyle.gradient.setRepeatMethod( VGradient::none ); |
||
1007 | QString style = m_styleStack.attribute( "draw:fill-gradient-name" ); |
||
1008 | QDomElement* draw = m_draws[style]; |
||
1009 | if( draw ) |
||
7293 | fschmid | 1010 | { |
8216 | jghali | 1011 | double border = 0.0; |
1012 | int shadeS = 100; |
||
1013 | int shadeE = 100; |
||
1014 | if( draw->hasAttribute( "draw:border" ) ) |
||
1015 | border += draw->attribute( "draw:border" ).remove( '%' ).toDouble() / 100.0; |
||
1016 | if( draw->hasAttribute( "draw:start-intensity" ) ) |
||
1017 | shadeS = draw->attribute( "draw:start-intensity" ).remove( '%' ).toInt(); |
||
1018 | if( draw->hasAttribute( "draw:end-intensity" ) ) |
||
1019 | shadeE = draw->attribute( "draw:end-intensity" ).remove( '%' ).toInt(); |
||
1020 | QString type = draw->attribute( "draw:style" ); |
||
1021 | if( type == "linear" || type == "axial" ) |
||
7293 | fschmid | 1022 | { |
8216 | jghali | 1023 | oostyle.gradient.setType( VGradient::linear ); |
1024 | oostyle.gradientAngle = draw->attribute( "draw:angle" ).toDouble() / 10; |
||
1025 | oostyle.gradientType = 1; |
||
7293 | fschmid | 1026 | } |
8216 | jghali | 1027 | else if( type == "radial" || type == "ellipsoid" ) |
1028 | { |
||
1029 | if( draw->hasAttribute( "draw:cx" ) ) |
||
1030 | oostyle.gradientPointX = draw->attribute( "draw:cx" ).remove( '%' ).toDouble() / 100.0; |
||
1031 | else |
||
1032 | oostyle.gradientPointX = 0.5; |
||
1033 | if( draw->hasAttribute( "draw:cy" ) ) |
||
1034 | oostyle.gradientPointY = draw->attribute( "draw:cy" ).remove( '%' ).toDouble() / 100.0; |
||
1035 | else |
||
1036 | oostyle.gradientPointY = 0.5; |
||
1037 | oostyle.gradientType = 2; |
||
1038 | } |
||
1039 | QString c, c2; |
||
1040 | c = parseColor( draw->attribute( "draw:start-color" ) ); |
||
1041 | c2 = parseColor( draw->attribute( "draw:end-color" ) ); |
||
1042 | const ScColor& col1 = m_Doc->PageColors[c]; |
||
1043 | const ScColor& col2 = m_Doc->PageColors[c2]; |
||
1044 | if (((oostyle.gradientAngle > 90) && (oostyle.gradientAngle < 271)) || (oostyle.gradientType == 2)) |
||
1045 | { |
||
1046 | const ScColor& col1 = m_Doc->PageColors[c]; |
||
1047 | const ScColor& col2 = m_Doc->PageColors[c2]; |
||
1048 | oostyle.gradient.addStop( ScColorEngine::getRGBColor(col2, m_Doc), 0.0, 0.5, 1, c2, shadeE ); |
||
1049 | oostyle.gradient.addStop( ScColorEngine::getRGBColor(col1, m_Doc), 1.0 - border, 0.5, 1, c, shadeS ); |
||
1050 | } |
||
1051 | else |
||
1052 | { |
||
1053 | oostyle.gradient.addStop( ScColorEngine::getRGBColor(col1, m_Doc), border, 0.5, 1, c, shadeS ); |
||
1054 | oostyle.gradient.addStop( ScColorEngine::getRGBColor(col2, m_Doc), 1.0, 0.5, 1, c2, shadeE ); |
||
1055 | } |
||
7293 | fschmid | 1056 | } |
1057 | } |
||
8216 | jghali | 1058 | } |
1059 | } |
||
1060 | |||
8368 | jghali | 1061 | void OODPlug::parseCharStyle(CharStyle& style, const QDomElement &e) |
8216 | jghali | 1062 | { |
8368 | jghali | 1063 | if ( m_styleStack.hasAttribute("fo:font-size") ) |
1064 | { |
||
1065 | QString fs = m_styleStack.attribute("fo:font-size").remove( "pt" ); |
||
1066 | int FontSize = (int) (fs.toFloat() * 10.0); |
||
1067 | style.setFontSize(FontSize); |
||
1068 | } |
||
1069 | } |
||
1070 | |||
1071 | void OODPlug::parseParagraphStyle(ParagraphStyle& style, const QDomElement &e) |
||
1072 | { |
||
1073 | if ( m_styleStack.hasAttribute("fo:text-align") ) |
||
1074 | { |
||
1075 | QString attValue = m_styleStack.attribute("fo:text-align"); |
||
1076 | if (attValue == "left") |
||
1077 | style.setAlignment(ParagraphStyle::Leftaligned); |
||
1078 | if (attValue == "center") |
||
1079 | style.setAlignment(ParagraphStyle::Centered); |
||
1080 | if (attValue == "right") |
||
1081 | style.setAlignment(ParagraphStyle::Rightaligned); |
||
1082 | } |
||
1083 | if ( m_styleStack.hasAttribute("fo:font-size") ) |
||
1084 | { |
||
1085 | QString fs = m_styleStack.attribute("fo:font-size").remove( "pt" ); |
||
1086 | int FontSize = (int) (fs.toFloat() * 10.0); |
||
1087 | style.charStyle().setFontSize(FontSize); |
||
1088 | style.setLineSpacing((FontSize + FontSize * 0.2) / 10.0); |
||
1089 | } |
||
1090 | } |
||
1091 | |||
1092 | PageItem* OODPlug::parseTextP (const QDomElement& elm, PageItem* item) |
||
1093 | { |
||
8216 | jghali | 1094 | for ( QDomNode n = elm.firstChild(); !n.isNull(); n = n.nextSibling() ) |
1095 | { |
||
1096 | if ( !n.hasAttributes() && !n.hasChildNodes() ) |
||
1097 | continue; |
||
1098 | QDomElement e = n.toElement(); |
||
1099 | if ( e.text().isEmpty() ) |
||
1100 | continue; |
||
8368 | jghali | 1101 | storeObjectStyles(e); |
8278 | jghali | 1102 | item->itemText.insertChars(-1, SpecialChars::PARSEP); |
8368 | jghali | 1103 | if (e.hasChildNodes()) |
1104 | item = parseTextSpans(e, item); |
||
1105 | else |
||
592 | fschmid | 1106 | { |
8368 | jghali | 1107 | if ( m_styleStack.hasAttribute("fo:text-align") || m_styleStack.hasAttribute("fo:font-size") ) |
8216 | jghali | 1108 | { |
8368 | jghali | 1109 | ParagraphStyle newStyle; |
1110 | parseParagraphStyle(newStyle, e); |
||
1111 | item->itemText.applyStyle(-1, newStyle); |
||
8216 | jghali | 1112 | } |
8368 | jghali | 1113 | item->itemText.insertChars(-2, QString::fromUtf8(e.text()) ); |
1114 | if (!item->asPolyLine() && !item->asTextFrame()) |
||
1115 | item = m_Doc->convertItemTo(item, PageItem::TextFrame); |
||
1116 | } |
||
1117 | |||
1118 | } |
||
1119 | return item; |
||
1120 | } |
||
1121 | |||
1122 | PageItem* OODPlug::parseTextSpans(const QDomElement& elm, PageItem* item) |
||
1123 | { |
||
1124 | bool firstSpan = true; |
||
1125 | for ( QDomNode n = elm.firstChild(); !n.isNull(); n = n.nextSibling() ) |
||
1126 | { |
||
1127 | QDomElement e = n.toElement(); |
||
1128 | QString sTag = e.tagName(); |
||
1129 | if (e.text().isEmpty() || sTag != "text:span") |
||
1130 | continue; |
||
1131 | storeObjectStyles(e); |
||
1132 | QString chars = e.text(); |
||
1133 | int pos = item->itemText.length(); |
||
1134 | if ( firstSpan && (m_styleStack.hasAttribute("fo:text-align") || m_styleStack.hasAttribute("fo:font-size")) ) |
||
1135 | { |
||
1136 | ParagraphStyle newStyle; |
||
1137 | parseParagraphStyle(newStyle, e); |
||
8278 | jghali | 1138 | item->itemText.applyStyle(-1, newStyle); |
592 | fschmid | 1139 | } |
8368 | jghali | 1140 | item->itemText.insertChars( -2, chars); |
1141 | if ( !firstSpan && m_styleStack.hasAttribute("fo:font-size") ) |
||
1142 | { |
||
1143 | CharStyle newStyle; |
||
1144 | parseCharStyle(newStyle, e); |
||
1145 | item->itemText.applyCharStyle(pos, chars.length(), newStyle); |
||
1146 | } |
||
8278 | jghali | 1147 | if (!item->asPolyLine() && !item->asTextFrame()) |
1148 | item = m_Doc->convertItemTo(item, PageItem::TextFrame); |
||
8368 | jghali | 1149 | firstSpan = false; |
8216 | jghali | 1150 | } |
8368 | jghali | 1151 | return item; |
1152 | } |
||
1153 | |||
1154 | PageItem* OODPlug::finishNodeParsing(const QDomElement &elm, PageItem* item, OODrawStyle& oostyle) |
||
1155 | { |
||
1156 | item->setTextToFrameDist(0.0, 0.0, 0.0, 0.0); |
||
8405 | fschmid | 1157 | // bool firstPa = false; |
8368 | jghali | 1158 | QString drawID = elm.attribute("draw:name"); |
1159 | item = parseTextP(elm, item); |
||
8278 | jghali | 1160 | item->setFillTransparency(oostyle.fillTrans); |
1161 | item->setLineTransparency(oostyle.strokeTrans); |
||
8216 | jghali | 1162 | if (oostyle.dashes.count() != 0) |
8278 | jghali | 1163 | item->DashValues = oostyle.dashes; |
8216 | jghali | 1164 | if (!drawID.isEmpty()) |
8278 | jghali | 1165 | item->setItemName(drawID); |
8216 | jghali | 1166 | if (elm.hasAttribute("draw:transform")) |
1167 | { |
||
8278 | jghali | 1168 | parseTransform(&item->PoLine, elm.attribute("draw:transform")); |
1169 | item->ClipEdited = true; |
||
1170 | item->FrameType = 3; |
||
1171 | FPoint wh = getMaxClipF(&item->PoLine); |
||
1172 | item->setWidthHeight(wh.x(), wh.y()); |
||
1173 | item->Clip = FlattenPath(item->PoLine, item->Segments); |
||
1174 | m_Doc->AdjustItemSize(item); |
||
8216 | jghali | 1175 | } |
8278 | jghali | 1176 | item->OwnPage = m_Doc->OnPage(item); |
8216 | jghali | 1177 | //ite->setTextFlowMode(PageItem::TextFlowUsesFrameShape); |
8278 | jghali | 1178 | item->setTextFlowMode(PageItem::TextFlowDisabled); |
8216 | jghali | 1179 | if (oostyle.haveGradient) |
1180 | { |
||
8278 | jghali | 1181 | item->GrType = 0; |
8216 | jghali | 1182 | if (oostyle.gradient.Stops() > 1) |
592 | fschmid | 1183 | { |
8278 | jghali | 1184 | item->fill_gradient = oostyle.gradient; |
8216 | jghali | 1185 | if (oostyle.gradientType == 1) |
544 | fschmid | 1186 | { |
8216 | jghali | 1187 | bool flipped = false; |
1188 | double gradientAngle(oostyle.gradientAngle); |
||
1189 | if ((gradientAngle == 0) || (gradientAngle == 180) || (gradientAngle == 90) || (gradientAngle == 270)) |
||
592 | fschmid | 1190 | { |
8216 | jghali | 1191 | if ((gradientAngle == 0) || (gradientAngle == 180)) |
8048 | avox | 1192 | { |
8278 | jghali | 1193 | item->GrType = 2; |
1194 | item->GrStartX = item->width() / 2.0; |
||
1195 | item->GrStartY = 0; |
||
1196 | item->GrEndX = item->width() / 2.0; |
||
1197 | item->GrEndY = item->height(); |
||
8048 | avox | 1198 | } |
8216 | jghali | 1199 | else if ((gradientAngle == 90) || (gradientAngle == 270)) |
1200 | { |
||
8278 | jghali | 1201 | item->GrType = 1; |
1202 | item->GrStartX = 0; |
||
1203 | item->GrStartY = item->height() / 2.0; |
||
1204 | item->GrEndX = item->width(); |
||
1205 | item->GrEndY = item->height() / 2.0; |
||
8216 | jghali | 1206 | } |
547 | fschmid | 1207 | } |
8216 | jghali | 1208 | else |
545 | fschmid | 1209 | { |
8216 | jghali | 1210 | if ((gradientAngle > 90) && (gradientAngle < 270)) |
1211 | gradientAngle -= 180; |
||
1212 | else if ((gradientAngle > 270) && (gradientAngle < 360)) |
||
546 | fschmid | 1213 | { |
8216 | jghali | 1214 | gradientAngle = 360 - gradientAngle; |
1215 | flipped = true; |
||
7351 | fschmid | 1216 | } |
8216 | jghali | 1217 | double xpos; |
8278 | jghali | 1218 | xpos = (item->width() / 2) * tan(gradientAngle* M_PI / 180.0) * (item->height() / item->width()) + (item->width() / 2); |
1219 | if ((xpos < 0) || (xpos > item->width())) |
||
7351 | fschmid | 1220 | { |
8278 | jghali | 1221 | xpos = (item->height() / 2)- (item->height() / 2) * tan(gradientAngle* M_PI / 180.0) * (item->height() / item->width()); |
8216 | jghali | 1222 | if (flipped) |
546 | fschmid | 1223 | { |
8278 | jghali | 1224 | item->GrEndX = item->width(); |
1225 | item->GrEndY = item->height() - xpos; |
||
1226 | item->GrStartX = 0; |
||
1227 | item->GrStartY = xpos; |
||
546 | fschmid | 1228 | } |
7351 | fschmid | 1229 | else |
546 | fschmid | 1230 | { |
8278 | jghali | 1231 | item->GrEndY = xpos; |
1232 | item->GrEndX = item->width(); |
||
1233 | item->GrStartX = 0; |
||
1234 | item->GrStartY = item->height() - xpos; |
||
546 | fschmid | 1235 | } |
1236 | } |
||
8216 | jghali | 1237 | else |
1238 | { |
||
8278 | jghali | 1239 | item->GrEndX = xpos; |
1240 | item->GrEndY = item->height(); |
||
1241 | item->GrStartX = item->width() - xpos; |
||
1242 | item->GrStartY = 0; |
||
8216 | jghali | 1243 | } |
1244 | if (flipped) |
||
1245 | { |
||
8278 | jghali | 1246 | item->GrEndX = item->width() - xpos; |
1247 | item->GrEndY = item->height(); |
||
1248 | item->GrStartX = xpos; |
||
1249 | item->GrStartY = 0; |
||
8216 | jghali | 1250 | } |
8278 | jghali | 1251 | item->GrType = 6; |
545 | fschmid | 1252 | } |
8216 | jghali | 1253 | } |
1254 | if (oostyle.gradientType == 2) |
||
1255 | { |
||
8278 | jghali | 1256 | item->GrType = 7; |
1257 | item->GrStartX = item->width() * oostyle.gradientPointX; |
||
1258 | item->GrStartY = item->height()* oostyle.gradientPointY; |
||
1259 | if (item->width() >= item->height()) |
||
8216 | jghali | 1260 | { |
8278 | jghali | 1261 | item->GrEndX = item->width(); |
1262 | item->GrEndY = item->height() / 2.0; |
||
8216 | jghali | 1263 | } |
7351 | fschmid | 1264 | else |
592 | fschmid | 1265 | { |
8278 | jghali | 1266 | item->GrEndX = item->width() / 2.0; |
1267 | item->GrEndY = item->height(); |
||
592 | fschmid | 1268 | } |
8216 | jghali | 1269 | //m_Doc->view()->updateGradientVectors(ite); |
8278 | jghali | 1270 | item->updateGradientVectors(); |
545 | fschmid | 1271 | } |
541 | fschmid | 1272 | } |
8216 | jghali | 1273 | else |
1274 | { |
||
1275 | QPtrVector<VColorStop> cstops = oostyle.gradient.colorStops(); |
||
8278 | jghali | 1276 | item->setFillColor(cstops.at(0)->name); |
1277 | item->setFillShade(cstops.at(0)->shade); |
||
8216 | jghali | 1278 | } |
541 | fschmid | 1279 | } |
8278 | jghali | 1280 | return item; |
541 | fschmid | 1281 | } |
1282 | |||
1283 | void OODPlug::createStyleMap( QDomDocument &docstyles ) |
||
1284 | { |
||
1285 | QDomElement styles = docstyles.documentElement(); |
||
1286 | if( styles.isNull() ) |
||
1287 | return; |
||
1288 | |||
1289 | QDomNode fixedStyles = styles.namedItem( "office:styles" ); |
||
1290 | if( !fixedStyles.isNull() ) |
||
1291 | { |
||
545 | fschmid | 1292 | insertDraws( fixedStyles.toElement() ); |
541 | fschmid | 1293 | insertStyles( fixedStyles.toElement() ); |
1294 | } |
||
1295 | QDomNode automaticStyles = styles.namedItem( "office:automatic-styles" ); |
||
1296 | if( !automaticStyles.isNull() ) |
||
1297 | insertStyles( automaticStyles.toElement() ); |
||
1298 | |||
1299 | QDomNode masterStyles = styles.namedItem( "office:master-styles" ); |
||
1300 | if( !masterStyles.isNull() ) |
||
1301 | insertStyles( masterStyles.toElement() ); |
||
1302 | } |
||
1303 | |||
545 | fschmid | 1304 | void OODPlug::insertDraws( const QDomElement& styles ) |
1305 | { |
||
1306 | for( QDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() ) |
||
1307 | { |
||
1308 | QDomElement e = n.toElement(); |
||
1309 | if( !e.hasAttribute( "draw:name" ) ) |
||
1310 | continue; |
||
1311 | QString name = e.attribute( "draw:name" ); |
||
1312 | m_draws.insert( name, new QDomElement( e ) ); |
||
1313 | } |
||
1314 | } |
||
1315 | |||
541 | fschmid | 1316 | void OODPlug::insertStyles( const QDomElement& styles ) |
1317 | { |
||
1318 | for ( QDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() ) |
||
1319 | { |
||
1320 | QDomElement e = n.toElement(); |
||
1321 | if( !e.hasAttribute( "style:name" ) ) |
||
1322 | continue; |
||
1323 | QString name = e.attribute( "style:name" ); |
||
1324 | m_styles.insert( name, new QDomElement( e ) ); |
||
1325 | } |
||
1326 | } |
||
1327 | |||
1328 | void OODPlug::fillStyleStack( const QDomElement& object ) |
||
1329 | { |
||
1330 | if( object.hasAttribute( "presentation:style-name" ) ) |
||
1331 | addStyles( m_styles[object.attribute( "presentation:style-name" )] ); |
||
1332 | if( object.hasAttribute( "draw:style-name" ) ) |
||
1333 | addStyles( m_styles[object.attribute( "draw:style-name" )] ); |
||
1334 | if( object.hasAttribute( "draw:text-style-name" ) ) |
||
1335 | addStyles( m_styles[object.attribute( "draw:text-style-name" )] ); |
||
1336 | if( object.hasAttribute( "text:style-name" ) ) |
||
1337 | addStyles( m_styles[object.attribute( "text:style-name" )] ); |
||
1338 | } |
||
1339 | |||
1340 | void OODPlug::addStyles( const QDomElement* style ) |
||
1341 | { |
||
1342 | if( style->hasAttribute( "style:parent-style-name" ) ) |
||
1343 | addStyles( m_styles[style->attribute( "style:parent-style-name" )] ); |
||
1344 | m_styleStack.push( *style ); |
||
1345 | } |
||
1346 | |||
1347 | void OODPlug::storeObjectStyles( const QDomElement& object ) |
||
1348 | { |
||
1349 | fillStyleStack( object ); |
||
1350 | } |
||
1351 | |||
1352 | double OODPlug::parseUnit(const QString &unit) |
||
1353 | { |
||
1354 | QString unitval=unit; |
||
2877 | cbradney | 1355 | if (unit.isEmpty()) |
541 | fschmid | 1356 | return 0.0; |
1357 | if( unit.right( 2 ) == "pt" ) |
||
1358 | unitval.replace( "pt", "" ); |
||
1359 | else if( unit.right( 2 ) == "cm" ) |
||
1360 | unitval.replace( "cm", "" ); |
||
1361 | else if( unit.right( 2 ) == "mm" ) |
||
1362 | unitval.replace( "mm" , "" ); |
||
1363 | else if( unit.right( 2 ) == "in" ) |
||
1364 | unitval.replace( "in", "" ); |
||
1365 | else if( unit.right( 2 ) == "px" ) |
||
1366 | unitval.replace( "px", "" ); |
||
1367 | double value = unitval.toDouble(); |
||
1368 | if( unit.right( 2 ) == "pt" ) |
||
1369 | value = value; |
||
1370 | else if( unit.right( 2 ) == "cm" ) |
||
1371 | value = ( value / 2.54 ) * 72; |
||
1372 | else if( unit.right( 2 ) == "mm" ) |
||
1373 | value = ( value / 25.4 ) * 72; |
||
1374 | else if( unit.right( 2 ) == "in" ) |
||
1375 | value = value * 72; |
||
1376 | else if( unit.right( 2 ) == "px" ) |
||
1377 | value = value; |
||
1378 | return value; |
||
1379 | } |
||
1380 | |||
1381 | QColor OODPlug::parseColorN( const QString &rgbColor ) |
||
1382 | { |
||
1383 | int r, g, b; |
||
1384 | keywordToRGB( rgbColor, r, g, b ); |
||
1385 | return QColor( r, g, b ); |
||
1386 | } |
||
1387 | |||
1388 | QString OODPlug::parseColor( const QString &s ) |
||
1389 | { |
||
1390 | QColor c; |
||
4546 | subik | 1391 | QString ret = CommonStrings::None; |
541 | fschmid | 1392 | if( s.startsWith( "rgb(" ) ) |
1393 | { |
||
1394 | QString parse = s.stripWhiteSpace(); |
||
1395 | QStringList colors = QStringList::split( ',', parse ); |
||
1396 | QString r = colors[0].right( ( colors[0].length() - 4 ) ); |
||
1397 | QString g = colors[1]; |
||
1398 | QString b = colors[2].left( ( colors[2].length() - 1 ) ); |
||
1399 | if( r.contains( "%" ) ) |
||
1400 | { |
||
1401 | r = r.left( r.length() - 1 ); |
||
1402 | r = QString::number( static_cast<int>( ( static_cast<double>( 255 * r.toDouble() ) / 100.0 ) ) ); |
||
1403 | } |
||
1404 | if( g.contains( "%" ) ) |
||
1405 | { |
||
1406 | g = g.left( g.length() - 1 ); |
||
1407 | g = QString::number( static_cast<int>( ( static_cast<double>( 255 * g.toDouble() ) / 100.0 ) ) ); |
||
1408 | } |
||
1409 | if( b.contains( "%" ) ) |
||
1410 | { |
||
1411 | b = b.left( b.length() - 1 ); |
||
1412 | b = QString::number( static_cast<int>( ( static_cast<double>( 255 * b.toDouble() ) / 100.0 ) ) ); |
||
1413 | } |
||
1414 | c = QColor(r.toInt(), g.toInt(), b.toInt()); |
||
1415 | } |
||
1416 | else |
||
1417 | { |
||
1418 | QString rgbColor = s.stripWhiteSpace(); |
||
1419 | if( rgbColor.startsWith( "#" ) ) |
||
1420 | c.setNamedColor( rgbColor ); |
||
1421 | else |
||
1422 | c = parseColorN( rgbColor ); |
||
1423 | } |
||
1065 | cbradney | 1424 | ColorList::Iterator it; |
541 | fschmid | 1425 | bool found = false; |
1488 | fschmid | 1426 | int r, g, b; |
1427 | QColor tmpR; |
||
5781 | cbradney | 1428 | for (it = m_Doc->PageColors.begin(); it != m_Doc->PageColors.end(); ++it) |
541 | fschmid | 1429 | { |
7554 | jghali | 1430 | if (it.data().getColorModel() == colorModelRGB) |
541 | fschmid | 1431 | { |
7554 | jghali | 1432 | it.data().getRGB(&r, &g, &b); |
1433 | tmpR.setRgb(r, g, b); |
||
1434 | if (c == tmpR) |
||
1435 | { |
||
1436 | ret = it.key(); |
||
1437 | found = true; |
||
1438 | } |
||
541 | fschmid | 1439 | } |
1440 | } |
||
1441 | if (!found) |
||
1442 | { |
||
2886 | fschmid | 1443 | ScColor tmp; |
541 | fschmid | 1444 | tmp.fromQColor(c); |
7491 | fschmid | 1445 | tmp.setSpotColor(false); |
1446 | tmp.setRegistrationColor(false); |
||
5781 | cbradney | 1447 | m_Doc->PageColors.insert("FromOODraw"+c.name(), tmp); |
7991 | fschmid | 1448 | importedColors.append("FromOODraw"+c.name()); |
541 | fschmid | 1449 | ret = "FromOODraw"+c.name(); |
1450 | } |
||
1451 | return ret; |
||
1452 | } |
||
1453 | |||
546 | fschmid | 1454 | void OODPlug::parseTransform(FPointArray *composite, const QString &transform) |
541 | fschmid | 1455 | { |
545 | fschmid | 1456 | double dx, dy; |
1457 | QWMatrix result; |
||
541 | fschmid | 1458 | QStringList subtransforms = QStringList::split(')', transform); |
1459 | QStringList::ConstIterator it = subtransforms.begin(); |
||
1460 | QStringList::ConstIterator end = subtransforms.end(); |
||
546 | fschmid | 1461 | for (; it != end; ++it) |
541 | fschmid | 1462 | { |
1463 | QStringList subtransform = QStringList::split('(', (*it)); |
||
1464 | subtransform[0] = subtransform[0].stripWhiteSpace().lower(); |
||
1465 | subtransform[1] = subtransform[1].simplifyWhiteSpace(); |
||
1466 | QRegExp reg("[,( ]"); |
||
1467 | QStringList params = QStringList::split(reg, subtransform[1]); |
||
1468 | if(subtransform[0].startsWith(";") || subtransform[0].startsWith(",")) |
||
1469 | subtransform[0] = subtransform[0].right(subtransform[0].length() - 1); |
||
1470 | if(subtransform[0] == "rotate") |
||
546 | fschmid | 1471 | { |
1472 | result = QWMatrix(); |
||
1795 | cbradney | 1473 | result.rotate(-parseUnit(params[0]) * 180 / M_PI); |
546 | fschmid | 1474 | composite->map(result); |
1475 | } |
||
541 | fschmid | 1476 | else if(subtransform[0] == "translate") |
1477 | { |
||
1478 | if(params.count() == 2) |
||
1479 | { |
||
545 | fschmid | 1480 | dx = parseUnit(params[0]); |
1481 | dy = parseUnit(params[1]); |
||
541 | fschmid | 1482 | } |
1483 | else |
||
1484 | { |
||
545 | fschmid | 1485 | dx = parseUnit(params[0]); |
1486 | dy =0.0; |
||
541 | fschmid | 1487 | } |
546 | fschmid | 1488 | result = QWMatrix(); |
545 | fschmid | 1489 | result.translate(dx, dy); |
546 | fschmid | 1490 | composite->map(result); |
541 | fschmid | 1491 | } |
545 | fschmid | 1492 | else if(subtransform[0] == "skewx") |
546 | fschmid | 1493 | { |
1494 | result = QWMatrix(); |
||
5720 | jghali | 1495 | result.shear(-tan(params[0].toDouble()), 0.0); |
546 | fschmid | 1496 | composite->map(result); |
1497 | } |
||
545 | fschmid | 1498 | else if(subtransform[0] == "skewy") |
546 | fschmid | 1499 | { |
1500 | result = QWMatrix(); |
||
5720 | jghali | 1501 | result.shear(0.0, -tan(params[0].toDouble())); |
546 | fschmid | 1502 | composite->map(result); |
1503 | } |
||
541 | fschmid | 1504 | } |
1505 | } |
||
1506 | |||
544 | fschmid | 1507 | void OODPlug::parseViewBox( const QDomElement& object, double *x, double *y, double *w, double *h ) |
541 | fschmid | 1508 | { |
544 | fschmid | 1509 | if( !object.attribute( "svg:viewBox" ).isEmpty() ) |
1510 | { |
||
1511 | QString viewbox( object.attribute( "svg:viewBox" ) ); |
||
1512 | QStringList points = QStringList::split( ' ', viewbox.replace( QRegExp(","), " ").simplifyWhiteSpace() ); |
||
1513 | *x = points[0].toDouble(); |
||
1514 | *y = points[1].toDouble(); |
||
1515 | *w = points[2].toDouble(); |
||
1516 | *h = points[3].toDouble(); |
||
1517 | } |
||
541 | fschmid | 1518 | } |
1519 | |||
544 | fschmid | 1520 | void OODPlug::appendPoints(FPointArray *composite, const QDomElement& object) |
541 | fschmid | 1521 | { |
544 | fschmid | 1522 | double x = parseUnit(object.attribute("svg:x")); |
1523 | double y = parseUnit(object.attribute("svg:y")) ; |
||
1524 | double w = parseUnit(object.attribute("svg:width")); |
||
1525 | double h = parseUnit(object.attribute("svg:height")); |
||
1526 | double vx = 0; |
||
1527 | double vy = 0; |
||
1528 | double vw = 1; |
||
1529 | double vh = 1; |
||
1530 | parseViewBox(object, &vx, &vy, &vw, &vh); |
||
1531 | QStringList ptList = QStringList::split( ' ', object.attribute( "draw:points" ) ); |
||
1532 | FPoint point, firstP; |
||
1533 | bool bFirst = true; |
||
1534 | for( QStringList::Iterator it = ptList.begin(); it != ptList.end(); ++it ) |
||
1535 | { |
||
1536 | point = FPoint((*it).section( ',', 0, 0 ).toDouble(), (*it).section( ',', 1, 1 ).toDouble()); |
||
1537 | if (bFirst) |
||
1538 | { |
||
1539 | composite->addPoint(point); |
||
1540 | composite->addPoint(point); |
||
1541 | firstP = point; |
||
1542 | bFirst = false; |
||
1543 | } |
||
1544 | else |
||
1545 | { |
||
1546 | composite->addPoint(point); |
||
1547 | composite->addPoint(point); |
||
1548 | composite->addPoint(point); |
||
1549 | composite->addPoint(point); |
||
1550 | } |
||
1551 | } |
||
1552 | composite->addPoint(firstP); |
||
1553 | composite->addPoint(firstP); |
||
1554 | QWMatrix mat; |
||
1555 | mat.translate(x, y); |
||
1556 | mat.scale(w / vw, h / vh); |
||
1557 | composite->map(mat); |
||
541 | fschmid | 1558 | } |
1559 | |||
544 | fschmid | 1560 | const char * OODPlug::getCoord( const char *ptr, double &number ) |
541 | fschmid | 1561 | { |
1562 | int integer, exponent; |
||
1563 | double decimal, frac; |
||
1564 | int sign, expsign; |
||
1565 | |||
1566 | exponent = 0; |
||
1567 | integer = 0; |
||
1568 | frac = 1.0; |
||
1569 | decimal = 0; |
||
1570 | sign = 1; |
||
1571 | expsign = 1; |
||
1572 | |||
544 | fschmid | 1573 | // read the sign |
541 | fschmid | 1574 | if(*ptr == '+') |
1575 | ptr++; |
||
1576 | else if(*ptr == '-') |
||
1577 | { |
||
1578 | ptr++; |
||
1579 | sign = -1; |
||
1580 | } |
||
1581 | |||
544 | fschmid | 1582 | // read the integer part |
541 | fschmid | 1583 | while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9') |
1584 | integer = (integer * 10) + *(ptr++) - '0'; |
||
544 | fschmid | 1585 | if(*ptr == '.') // read the decimals |
541 | fschmid | 1586 | { |
1587 | ptr++; |
||
1588 | while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9') |
||
1589 | decimal += (*(ptr++) - '0') * (frac *= 0.1); |
||
1590 | } |
||
1591 | |||
544 | fschmid | 1592 | if(*ptr == 'e' || *ptr == 'E') // read the exponent part |
541 | fschmid | 1593 | { |
1594 | ptr++; |
||
1595 | |||
544 | fschmid | 1596 | // read the sign of the exponent |
541 | fschmid | 1597 | if(*ptr == '+') |
1598 | ptr++; |
||
1599 | else if(*ptr == '-') |
||
1600 | { |
||
1601 | ptr++; |
||
1602 | expsign = -1; |
||
1603 | } |
||
1604 | |||
1605 | exponent = 0; |
||
1606 | while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9') |
||
1607 | { |
||
1608 | exponent *= 10; |
||
1609 | exponent += *ptr - '0'; |
||
1610 | ptr++; |
||
1611 | } |
||
1612 | } |
||
1613 | number = integer + decimal; |
||
1614 | number *= sign * pow( static_cast<double>(10), static_cast<double>( expsign * exponent ) ); |
||
1615 | |||
544 | fschmid | 1616 | // skip the following space |
541 | fschmid | 1617 | if(*ptr == ' ') |
1618 | ptr++; |
||
1619 | |||
1620 | return ptr; |
||
1621 | } |
||
1622 | |||
544 | fschmid | 1623 | bool OODPlug::parseSVG( const QString &s, FPointArray *ite ) |
541 | fschmid | 1624 | { |
1625 | QString d = s; |
||
1626 | d = d.replace( QRegExp( "," ), " "); |
||
1627 | bool ret = false; |
||
1628 | if( !d.isEmpty() ) |
||
1629 | { |
||
1630 | d = d.simplifyWhiteSpace(); |
||
1631 | const char *ptr = d.latin1(); |
||
1632 | const char *end = d.latin1() + d.length() + 1; |
||
1633 | double contrlx, contrly, curx, cury, subpathx, subpathy, tox, toy, x1, y1, x2, y2, xc, yc; |
||
1634 | double px1, py1, px2, py2, px3, py3; |
||
1635 | bool relative; |
||
1636 | FirstM = true; |
||
1637 | char command = *(ptr++), lastCommand = ' '; |
||
1638 | subpathx = subpathy = curx = cury = contrlx = contrly = 0.0; |
||
1639 | while( ptr < end ) |
||
1640 | { |
||
1641 | if( *ptr == ' ' ) |
||
1642 | ptr++; |
||
1643 | relative = false; |
||
1644 | switch( command ) |
||
1645 | { |
||
1646 | case 'm': |
||
1647 | relative = true; |
||
1648 | case 'M': |
||
1649 | { |
||
1650 | ptr = getCoord( ptr, tox ); |
||
1651 | ptr = getCoord( ptr, toy ); |
||
1652 | WasM = true; |
||
1653 | subpathx = curx = relative ? curx + tox : tox; |
||
1654 | subpathy = cury = relative ? cury + toy : toy; |
||
1655 | svgMoveTo(curx, cury ); |
||
1656 | break; |
||
1657 | } |
||
1658 | case 'l': |
||
1659 | relative = true; |
||
1660 | case 'L': |
||
1661 | { |
||
1662 | ptr = getCoord( ptr, tox ); |
||
1663 | ptr = getCoord( ptr, toy ); |
||
1664 | curx = relative ? curx + tox : tox; |
||
1665 | cury = relative ? cury + toy : toy; |
||
1666 | svgLineTo(ite, curx, cury ); |
||
1667 | break; |
||
1668 | } |
||
1669 | case 'h': |
||
1670 | { |
||
1671 | ptr = getCoord( ptr, tox ); |
||
1672 | curx = curx + tox; |
||
1673 | svgLineTo(ite, curx, cury ); |
||
1674 | break; |
||
1675 | } |
||
1676 | case 'H': |
||
1677 | { |
||
1678 | ptr = getCoord( ptr, tox ); |
||
1679 | curx = tox; |
||
1680 | svgLineTo(ite, curx, cury ); |
||
1681 | break; |
||
1682 | } |
||
1683 | case 'v': |
||
1684 | { |
||
1685 | ptr = getCoord( ptr, toy ); |
||
1686 | cury = cury + toy; |
||
1687 | svgLineTo(ite, curx, cury ); |
||
1688 | break; |
||
1689 | } |
||
1690 | case 'V': |
||
1691 | { |
||
1692 | ptr = getCoord( ptr, toy ); |
||
1693 | cury = toy; |
||
1694 | svgLineTo(ite, curx, cury ); |
||
1695 | break; |
||
1696 | } |
||
1697 | case 'z': |
||
1698 | case 'Z': |
||
1699 | { |
||
587 | fschmid | 1700 | // curx = subpathx; |
1701 | // cury = subpathy; |
||
541 | fschmid | 1702 | svgClosePath(ite); |
1703 | break; |
||
1704 | } |
||
1705 | case 'c': |
||
1706 | relative = true; |
||
1707 | case 'C': |
||
1708 | { |
||
1709 | ptr = getCoord( ptr, x1 ); |
||
1710 | ptr = getCoord( ptr, y1 ); |
||
1711 | ptr = getCoord( ptr, x2 ); |
||
1712 | ptr = getCoord( ptr, y2 ); |
||
1713 | ptr = getCoord( ptr, tox ); |
||
1714 | ptr = getCoord( ptr, toy ); |
||
1715 | px1 = relative ? curx + x1 : x1; |
||
1716 | py1 = relative ? cury + y1 : y1; |
||
1717 | px2 = relative ? curx + x2 : x2; |
||
1718 | py2 = relative ? cury + y2 : y2; |
||
1719 | px3 = relative ? curx + tox : tox; |
||
1720 | py3 = relative ? cury + toy : toy; |
||
1721 | svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 ); |
||
1722 | contrlx = relative ? curx + x2 : x2; |
||
1723 | contrly = relative ? cury + y2 : y2; |
||
1724 | curx = relative ? curx + tox : tox; |
||
1725 | cury = relative ? cury + toy : toy; |
||
1726 | break; |
||
1727 | } |
||
1728 | case 's': |
||
1729 | relative = true; |
||
1730 | case 'S': |
||
1731 | { |
||
1732 | ptr = getCoord( ptr, x2 ); |
||
1733 | ptr = getCoord( ptr, y2 ); |
||
1734 | ptr = getCoord( ptr, tox ); |
||
1735 | ptr = getCoord( ptr, toy ); |
||
1736 | px1 = 2 * curx - contrlx; |
||
1737 | py1 = 2 * cury - contrly; |
||
1738 | px2 = relative ? curx + x2 : x2; |
||
1739 | py2 = relative ? cury + y2 : y2; |
||
1740 | px3 = relative ? curx + tox : tox; |
||
1741 | py3 = relative ? cury + toy : toy; |
||
1742 | svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 ); |
||
1743 | contrlx = relative ? curx + x2 : x2; |
||
1744 | contrly = relative ? cury + y2 : y2; |
||
1745 | curx = relative ? curx + tox : tox; |
||
1746 | cury = relative ? cury + toy : toy; |
||
1747 | break; |
||
1748 | } |
||
1749 | case 'q': |
||
1750 | relative = true; |
||
1751 | case 'Q': |
||
1752 | { |
||
1753 | ptr = getCoord( ptr, x1 ); |
||
1754 | ptr = getCoord( ptr, y1 ); |
||
1755 | ptr = getCoord( ptr, tox ); |
||
1756 | ptr = getCoord( ptr, toy ); |
||
1757 | px1 = relative ? (curx + 2 * (x1 + curx)) * (1.0 / 3.0) : (curx + 2 * x1) * (1.0 / 3.0); |
||
1758 | py1 = relative ? (cury + 2 * (y1 + cury)) * (1.0 / 3.0) : (cury + 2 * y1) * (1.0 / 3.0); |
||
1759 | px2 = relative ? ((curx + tox) + 2 * (x1 + curx)) * (1.0 / 3.0) : (tox + 2 * x1) * (1.0 / 3.0); |
||
1760 | py2 = relative ? ((cury + toy) + 2 * (y1 + cury)) * (1.0 / 3.0) : (toy + 2 * y1) * (1.0 / 3.0); |
||
1761 | px3 = relative ? curx + tox : tox; |
||
1762 | py3 = relative ? cury + toy : toy; |
||
1763 | svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 ); |
||
1764 | contrlx = relative ? curx + x1 : (tox + 2 * x1) * (1.0 / 3.0); |
||
1765 | contrly = relative ? cury + y1 : (toy + 2 * y1) * (1.0 / 3.0); |
||
1766 | curx = relative ? curx + tox : tox; |
||
1767 | cury = relative ? cury + toy : toy; |
||
1768 | break; |
||
1769 | } |
||
1770 | case 't': |
||
1771 | relative = true; |
||
1772 | case 'T': |
||
1773 | { |
||
1774 | ptr = getCoord(ptr, tox); |
||
1775 | ptr = getCoord(ptr, toy); |
||
1776 | xc = 2 * curx - contrlx; |
||
1777 | yc = 2 * cury - contrly; |
||
1778 | px1 = relative ? (curx + 2 * xc) * (1.0 / 3.0) : (curx + 2 * xc) * (1.0 / 3.0); |
||
1779 | py1 = relative ? (cury + 2 * yc) * (1.0 / 3.0) : (cury + 2 * yc) * (1.0 / 3.0); |
||
1780 | px2 = relative ? ((curx + tox) + 2 * xc) * (1.0 / 3.0) : (tox + 2 * xc) * (1.0 / 3.0); |
||
1781 | py2 = relative ? ((cury + toy) + 2 * yc) * (1.0 / 3.0) : (toy + 2 * yc) * (1.0 / 3.0); |
||
1782 | px3 = relative ? curx + tox : tox; |
||
1783 | py3 = relative ? cury + toy : toy; |
||
1784 | svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 ); |
||
1785 | contrlx = xc; |
||
1786 | contrly = yc; |
||
1787 | curx = relative ? curx + tox : tox; |
||
1788 | cury = relative ? cury + toy : toy; |
||
1789 | break; |
||
1790 | } |
||
1791 | case 'a': |
||
1792 | relative = true; |
||
1793 | case 'A': |
||
1794 | { |
||
1795 | bool largeArc, sweep; |
||
1796 | double angle, rx, ry; |
||
1797 | ptr = getCoord( ptr, rx ); |
||
1798 | ptr = getCoord( ptr, ry ); |
||
1799 | ptr = getCoord( ptr, angle ); |
||
1800 | ptr = getCoord( ptr, tox ); |
||
1801 | largeArc = tox == 1; |
||
1802 | ptr = getCoord( ptr, tox ); |
||
1803 | sweep = tox == 1; |
||
1804 | ptr = getCoord( ptr, tox ); |
||
1805 | ptr = getCoord( ptr, toy ); |
||
1806 | calculateArc(ite, relative, curx, cury, angle, tox, toy, rx, ry, largeArc, sweep ); |
||
1807 | } |
||
1808 | } |
||
1809 | lastCommand = command; |
||
1810 | if(*ptr == '+' || *ptr == '-' || (*ptr >= '0' && *ptr <= '9')) |
||
1811 | { |
||
1812 | // there are still coords in this command |
||
1813 | if(command == 'M') |
||
1814 | command = 'L'; |
||
1815 | else if(command == 'm') |
||
1816 | command = 'l'; |
||
1817 | } |
||
1818 | else |
||
1819 | command = *(ptr++); |
||
1820 | |||
1821 | if( lastCommand != 'C' && lastCommand != 'c' && |
||
1822 | lastCommand != 'S' && lastCommand != 's' && |
||
1823 | lastCommand != 'Q' && lastCommand != 'q' && |
||
1824 | lastCommand != 'T' && lastCommand != 't') |
||
1825 | { |
||
1826 | contrlx = curx; |
||
1827 | contrly = cury; |
||
1828 | } |
||
1829 | } |
||
1830 | if ((lastCommand != 'z') && (lastCommand != 'Z')) |
||
1831 | ret = true; |
||
1832 | if (ite->size() > 2) |
||
1833 | { |
||
1834 | if ((ite->point(0).x() == ite->point(ite->size()-2).x()) && (ite->point(0).y() == ite->point(ite->size()-2).y())) |
||
1835 | ret = false; |
||
1836 | } |
||
1837 | } |
||
1838 | return ret; |
||
1839 | } |
||
1840 | |||
544 | fschmid | 1841 | void OODPlug::calculateArc(FPointArray *ite, bool relative, double &curx, double &cury, double angle, double x, double y, double r1, double r2, bool largeArcFlag, bool sweepFlag) |
541 | fschmid | 1842 | { |
1843 | double sin_th, cos_th; |
||
1844 | double a00, a01, a10, a11; |
||
1845 | double x0, y0, x1, y1, xc, yc; |
||
1846 | double d, sfactor, sfactor_sq; |
||
1847 | double th0, th1, th_arc; |
||
1848 | int i, n_segs; |
||
1849 | sin_th = sin(angle * (M_PI / 180.0)); |
||
1850 | cos_th = cos(angle * (M_PI / 180.0)); |
||
1851 | double dx; |
||
1852 | if(!relative) |
||
1853 | dx = (curx - x) / 2.0; |
||
1854 | else |
||
1855 | dx = -x / 2.0; |
||
1856 | double dy; |
||
1857 | if(!relative) |
||
1858 | dy = (cury - y) / 2.0; |
||
1859 | else |
||
1860 | dy = -y / 2.0; |
||
1861 | double _x1 = cos_th * dx + sin_th * dy; |
||
1862 | double _y1 = -sin_th * dx + cos_th * dy; |
||
1863 | double Pr1 = r1 * r1; |
||
1864 | double Pr2 = r2 * r2; |
||
1865 | double Px = _x1 * _x1; |
||
1866 | double Py = _y1 * _y1; |
||
1867 | double check = Px / Pr1 + Py / Pr2; |
||
1868 | if(check > 1) |
||
1869 | { |
||
1870 | r1 = r1 * sqrt(check); |
||
1871 | r2 = r2 * sqrt(check); |
||
1872 | } |
||
1873 | a00 = cos_th / r1; |
||
1874 | a01 = sin_th / r1; |
||
1875 | a10 = -sin_th / r2; |
||
1876 | a11 = cos_th / r2; |
||
1877 | x0 = a00 * curx + a01 * cury; |
||
1878 | y0 = a10 * curx + a11 * cury; |
||
1879 | if(!relative) |
||
1880 | x1 = a00 * x + a01 * y; |
||
1881 | else |
||
1882 | x1 = a00 * (curx + x) + a01 * (cury + y); |
||
1883 | if(!relative) |
||
1884 | y1 = a10 * x + a11 * y; |
||
1885 | else |
||
1886 | y1 = a10 * (curx + x) + a11 * (cury + y); |
||
1887 | d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0); |
||
1888 | sfactor_sq = 1.0 / d - 0.25; |
||
1889 | if(sfactor_sq < 0) |
||
1890 | sfactor_sq = 0; |
||
1891 | sfactor = sqrt(sfactor_sq); |
||
1892 | if(sweepFlag == largeArcFlag) |
||
1893 | sfactor = -sfactor; |
||
1894 | xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0); |
||
1895 | yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0); |
||
1896 | |||
1897 | th0 = atan2(y0 - yc, x0 - xc); |
||
1898 | th1 = atan2(y1 - yc, x1 - xc); |
||
1899 | th_arc = th1 - th0; |
||
1900 | if(th_arc < 0 && sweepFlag) |
||
1901 | th_arc += 2 * M_PI; |
||
1902 | else if(th_arc > 0 && !sweepFlag) |
||
1903 | th_arc -= 2 * M_PI; |
||
1904 | n_segs = static_cast<int>(ceil(fabs(th_arc / (M_PI * 0.5 + 0.001)))); |
||
1905 | for(i = 0; i < n_segs; i++) |
||
1906 | { |
||
1907 | { |
||
1908 | double sin_th, cos_th; |
||
1909 | double a00, a01, a10, a11; |
||
1910 | double x1, y1, x2, y2, x3, y3; |
||
1911 | double t; |
||
1912 | double th_half; |
||
1913 | double _th0 = th0 + i * th_arc / n_segs; |
||
1914 | double _th1 = th0 + (i + 1) * th_arc / n_segs; |
||
1915 | sin_th = sin(angle * (M_PI / 180.0)); |
||
1916 | cos_th = cos(angle * (M_PI / 180.0)); |
||
1917 | a00 = cos_th * r1; |
||
1918 | a01 = -sin_th * r2; |
||
1919 | a10 = sin_th * r1; |
||
1920 | a11 = cos_th * r2; |
||
1921 | th_half = 0.5 * (_th1 - _th0); |
||
1922 | t = (8.0 / 3.0) * sin(th_half * 0.5) * sin(th_half * 0.5) / sin(th_half); |
||
1923 | x1 = xc + cos(_th0) - t * sin(_th0); |
||
1924 | y1 = yc + sin(_th0) + t * cos(_th0); |
||
1925 | x3 = xc + cos(_th1); |
||
1926 | y3 = yc + sin(_th1); |
||
1927 | x2 = x3 + t * sin(_th1); |
||
1928 | y2 = y3 - t * cos(_th1); |
||
1929 | svgCurveToCubic(ite, a00 * x1 + a01 * y1, a10 * x1 + a11 * y1, a00 * x2 + a01 * y2, a10 * x2 + a11 * y2, a00 * x3 + a01 * y3, a10 * x3 + a11 * y3 ); |
||
1930 | } |
||
1931 | } |
||
1932 | if(!relative) |
||
1933 | curx = x; |
||
1934 | else |
||
1935 | curx += x; |
||
1936 | if(!relative) |
||
1937 | cury = y; |
||
1938 | else |
||
1939 | cury += y; |
||
1940 | } |
||
1941 | |||
544 | fschmid | 1942 | void OODPlug::svgMoveTo(double x1, double y1) |
541 | fschmid | 1943 | { |
1944 | CurrX = x1; |
||
1945 | CurrY = y1; |
||
1946 | StartX = x1; |
||
1947 | StartY = y1; |
||
1948 | PathLen = 0; |
||
1949 | } |
||
1950 | |||
544 | fschmid | 1951 | void OODPlug::svgLineTo(FPointArray *i, double x1, double y1) |
541 | fschmid | 1952 | { |
1953 | if ((!FirstM) && (WasM)) |
||
1954 | { |
||
1955 | i->setMarker(); |
||
1956 | PathLen += 4; |
||
1957 | } |
||
1958 | FirstM = false; |
||
1959 | WasM = false; |
||
1960 | if (i->size() > 3) |
||
1961 | { |
||
1962 | FPoint b1 = i->point(i->size()-4); |
||
1963 | FPoint b2 = i->point(i->size()-3); |
||
1964 | FPoint b3 = i->point(i->size()-2); |
||
1965 | FPoint b4 = i->point(i->size()-1); |
||
1966 | FPoint n1 = FPoint(CurrX, CurrY); |
||
1967 | FPoint n2 = FPoint(x1, y1); |
||
1968 | if ((b1 == n1) && (b2 == n1) && (b3 == n2) && (b4 == n2)) |
||
1969 | return; |
||
1970 | } |
||
1971 | i->addPoint(FPoint(CurrX, CurrY)); |
||
1972 | i->addPoint(FPoint(CurrX, CurrY)); |
||
1973 | i->addPoint(FPoint(x1, y1)); |
||
1974 | i->addPoint(FPoint(x1, y1)); |
||
1975 | CurrX = x1; |
||
1976 | CurrY = y1; |
||
1977 | PathLen += 4; |
||
1978 | } |
||
1979 | |||
544 | fschmid | 1980 | void OODPlug::svgCurveToCubic(FPointArray *i, double x1, double y1, double x2, double y2, double x3, double y3) |
541 | fschmid | 1981 | { |
1982 | if ((!FirstM) && (WasM)) |
||
1983 | { |
||
1984 | i->setMarker(); |
||
1985 | PathLen += 4; |
||
1986 | } |
||
1987 | FirstM = false; |
||
1988 | WasM = false; |
||
1989 | if (PathLen > 3) |
||
1990 | { |
||
1991 | FPoint b1 = i->point(i->size()-4); |
||
1992 | FPoint b2 = i->point(i->size()-3); |
||
1993 | FPoint b3 = i->point(i->size()-2); |
||
1994 | FPoint b4 = i->point(i->size()-1); |
||
1995 | FPoint n1 = FPoint(CurrX, CurrY); |
||
1996 | FPoint n2 = FPoint(x1, y1); |
||
1997 | FPoint n3 = FPoint(x3, y3); |
||
1998 | FPoint n4 = FPoint(x2, y2); |
||
1999 | if ((b1 == n1) && (b2 == n2) && (b3 == n3) && (b4 == n4)) |
||