3 #include <qmessagebox.h>
5 #include <q3stylesheet.h>
12 #include "linkablemapobj.h"
16 static BranchObj *lastBranch;
17 static FloatObj *lastFloat;
18 static OrnamentedObj *lastOO;
20 extern Settings settings;
22 mapBuilderHandler::mapBuilderHandler() {}
24 mapBuilderHandler::~mapBuilderHandler() {}
26 QString mapBuilderHandler::errorProtocol() { return errorProt; }
28 bool mapBuilderHandler::startDocument()
32 laststate = StateInit;
40 QString mapBuilderHandler::parseHREF(QString href)
42 QString type=href.section(":",0,0);
43 QString path=href.section(":",1,1);
44 if (!tmpDir.endsWith("/"))
45 return tmpDir + "/" + path;
50 bool mapBuilderHandler::startElement ( const QString&, const QString&,
51 const QString& eName, const QXmlAttributes& atts )
55 cout << "startElement <"<< eName.ascii()<<
57 " laststate="<<laststate<<
58 " loadMode="<<loadMode<<endl;
60 if ( state == StateInit && (eName == "vymmap") )
63 if (!atts.value( "version").isEmpty() )
65 if (!checkVersion(atts.value("version")))
66 QMessageBox::warning( 0, "Warning: Version Problem" ,
67 "<h3>Map is newer than VYM</h3>"
68 "<p>The map you are just trying to load was "
69 "saved using vym " +atts.value("version")+". "
70 "The version of this vym is " __VYM_VERSION
71 ". If you run into problems after pressing "
72 "the ok-button below, updating vym should help.");
74 mc->setVersion(atts.value( "version" ));
77 if (loadMode==NewMap ||
78 (loadMode==ImportReplace && me->getSelection()==mc))
80 if (!atts.value( "author").isEmpty() )
82 mc->setAuthor(atts.value( "author" ) );
84 if (!atts.value( "comment").isEmpty() )
86 mc->setComment (atts.value( "comment" ) );
88 if (!atts.value( "backgroundColor").isEmpty() )
90 col.setNamedColor(atts.value("backgroundColor"));
91 mc->getCanvas()->setBackgroundColor(col);
93 if (!atts.value( "linkColorHint").isEmpty() )
95 if (atts.value("linkColorHint")=="HeadingColor")
96 me->setMapLinkColorHint(HeadingColor);
98 me->setMapLinkColorHint(DefaultColor);
100 if (!atts.value( "linkStyle").isEmpty() )
102 me->setMapLinkStyle(atts.value("linkStyle"));
104 if (!atts.value( "linkColor").isEmpty() )
106 col.setNamedColor(atts.value("linkColor"));
107 me->setMapDefLinkColor(col);
109 if (!atts.value( "defXLinkColor").isEmpty() )
111 col.setNamedColor(atts.value("defXLinkColor"));
112 me->setMapDefXLinkColor(col);
114 if (!atts.value( "defXLinkWidth").isEmpty() )
116 me->setMapDefXLinkWidth(atts.value("defXLinkWidth").toInt ());
119 } else if ( eName == "select" && state == StateMap )
121 state=StateMapSelect;
122 } else if ( eName == "setting" && state == StateMap )
124 state=StateMapSetting;
125 if (loadMode==NewMap)
126 readSettingAttr (atts);
127 } else if ( eName == "mapcenter" && state == StateMap )
129 state=StateMapCenter;
130 if (loadMode==NewMap)
132 // Really use the found mapcenter as MCO in a new map
133 lastBranch=mc; // avoid empty pointer
136 // Treat the found mapcenter as a branch
137 // in an existing map
138 LinkableMapObj* lmo=me->getSelection();
139 if (lmo && (typeid(*lmo) == typeid(BranchObj) )
140 || (typeid(*lmo) == typeid(MapCenterObj) ) )
142 lastBranch=(BranchObj*)lmo;
143 if (loadMode==ImportAdd)
145 lastBranch->addBranch();
146 lastBranch=lastBranch->getLastBranch();
152 readBranchAttr (atts);
153 } else if ( (eName == "standardflag" ||eName == "standardFlag") && state == StateMapCenter)
155 state=StateMapCenterStandardFlag;
156 } else if ( eName == "heading" && state == StateMapCenter)
158 state=StateMapCenterHeading;
159 if (!atts.value( "textColor").isEmpty() )
161 col.setNamedColor(atts.value("textColor"));
162 lastBranch->setColor(col );
164 } else if ( eName == "note" && state == StateMapCenter)
165 { // only for backward compatibility (<1.4.6). Use htmlnote now.
166 state=StateMapCenterNote;
167 if (!readNoteAttr (atts) ) return false;
168 } else if ( eName == "htmlnote" && state == StateMapCenter)
172 } else if ( eName == "floatimage" && state == StateMapCenter )
174 state=StateMapCenterFloatImage;
175 lastBranch->addFloatImage();
176 lastFloat=lastBranch->getLastFloatImage();
177 if (!readFloatImageAttr(atts)) return false;
178 } else if ( (eName == "branch"||eName=="floatimage") && state == StateMap)
180 // This is used in vymparts, which have no mapcenter!
182 LinkableMapObj* lmo=me->getSelection();
185 // If a vym part is _loaded_ (not imported),
186 // selection==lmo==NULL
187 // Treat it like ImportAdd then...
191 if (lmo && (typeid(*lmo) == typeid(BranchObj) )
192 || (typeid(*lmo) == typeid(MapCenterObj) ) )
194 lastBranch=(BranchObj*)(lmo);
198 if (loadMode==ImportAdd)
200 lastBranch->addBranch();
201 lastBranch=lastBranch->getLastBranch();
206 readBranchAttr (atts);
207 } else if (eName=="floatimage")
209 state=StateFloatImage;
210 lastBranch->addFloatImage();
211 lastFloat=lastBranch->getLastFloatImage();
212 if (!readFloatImageAttr(atts)) return false;
215 } else if ( eName == "branch" && state == StateMapCenter)
219 lastBranch->addBranch();
220 lastBranch=lastBranch->getLastBranch();
221 readBranchAttr (atts);
222 } else if ( (eName=="standardflag" ||eName == "standardFlag") && state == StateBranch)
224 state=StateBranchStandardFlag;
225 } else if ( eName == "heading" && state == StateBranch)
227 state=StateBranchHeading;
228 if (!atts.value( "textColor").isEmpty() )
230 col.setNamedColor(atts.value("textColor"));
231 lastBranch->setColor(col );
233 } else if ( eName == "note" && state == StateBranch)
235 state=StateBranchNote;
236 if (!readNoteAttr (atts) ) return false;
237 } else if ( eName == "htmlnote" && state == StateBranch)
242 if (!atts.value( "fonthint").isEmpty() )
243 no.setFontHint(atts.value ("fonthint") );
244 } else if ( eName == "floatimage" && state == StateBranch )
246 state=StateBranchFloatImage;
247 lastBranch->addFloatImage();
248 lastFloat=lastBranch->getLastFloatImage();
249 if (!readFloatImageAttr(atts)) return false;
250 } else if ( eName == "xlink" && state == StateBranch )
252 state=StateBranchXLink;
253 if (!readXLinkAttr (atts)) return false;
254 } else if ( eName == "branch" && state == StateBranch )
256 lastBranch->addBranch();
257 lastBranch=lastBranch->getLastBranch();
259 readBranchAttr (atts);
260 } else if ( eName == "html" && state == StateHtmlNote )
266 } else if ( state == StateHtml )
268 // accept all while in html mode,
273 return false; // Error
277 bool mapBuilderHandler::endElement ( const QString&, const QString&, const QString &eName)
279 // cout << "endElement </"<<eName<<"> state="<<state <<" laststate="<<laststate<<endl;
282 case StateMapSelect: state=StateMap; return true;
283 case StateMapSetting: state=StateMap; return true;
284 case StateMapCenter: state=StateMap; return true;
285 case StateMapCenterStandardFlag: state=StateMapCenter; return true;
286 case StateMapCenterHeading: state=StateMapCenter; return true;
287 case StateMapCenterNote: state=StateMapCenter; return true;
288 case StateMapCenterFloatImage: state=StateMapCenter; return true;
289 case StateFloatImage: state=StateMap; return true;
301 state=StateMapCenter;
303 lastBranch=(BranchObj*)(lastBranch->getParObj());
305 case StateBranchStandardFlag: state=StateBranch; return true;
306 case StateBranchHeading: state=StateBranch; return true;
307 case StateBranchNote: state=StateBranch; return true;
308 case StateBranchFloatImage: state=StateBranch; return true;
309 case StateBranchXLink: state=StateBranch; return true;
310 case StateHtmlNote: state=laststate; return true;
312 htmldata+="</"+eName+">";
316 htmldata.replace ("<br></br>","<br />");
317 no.setNote (htmldata);
318 lastBranch->setNote (no);
324 case StateMap: state=StateInit; return true;
326 // even for HTML includes, this should never be reached
331 bool mapBuilderHandler::characters ( const QString& ch)
333 //cout << "characters \""<<ch<<"\" state="<<state <<" laststate="<<laststate<<endl;
335 QString ch_org=quotemeta (ch);
336 QString ch_simplified=ch.simplifyWhiteSpace();
337 if ( ch_simplified.isEmpty() ) return true;
341 case StateInit: break;
342 case StateMap: break;
344 me->select(ch_simplified);
346 case StateMapSetting:break;
347 case StateMapCenter: break;
348 case StateMapCenterStandardFlag:
349 lastBranch->activateStandardFlag(ch_simplified);
351 case StateMapCenterHeading:
352 lastBranch->setHeading(ch_simplified);
354 case StateMapCenterNote:
355 lastBranch->setNote(ch_simplified);
357 case StateBranch: break;
358 case StateBranchStandardFlag:
359 lastBranch->activateStandardFlag(ch_simplified);
361 case StateBranchHeading:
362 lastBranch->setHeading(ch_simplified);
364 case StateBranchNote:
365 lastBranch->setNote(ch_simplified);
367 case StateBranchFloatImage: break;
368 case StateHtmlNote: break;
378 QString mapBuilderHandler::errorString()
380 return "the document is not in the VYM file format";
383 bool mapBuilderHandler::fatalError( const QXmlParseException& exception )
385 errorProt += QString( "Fatal parsing error: %1 in line %2, column %3\n")
386 .arg( exception.message() )
387 .arg( exception.lineNumber() )
388 .arg( exception.columnNumber() );
389 // Try to read the bogus line
390 errorProt+=QString("File is: %1\n").arg(inputFile);
392 if (loadStringFromDisk (inputFile,s))
394 QStringList sl=QStringList::split ("\n",s);
396 QStringList::Iterator it = sl.begin();
397 while (i<exception.lineNumber()-1)
403 s.insert (exception.columnNumber()-1,"<ERROR>");
406 return QXmlDefaultHandler::fatalError( exception );
409 void mapBuilderHandler::setMapEditor (MapEditor* e)
412 mc=me->getMapCenter();
415 void mapBuilderHandler::setTmpDir (QString tp)
420 void mapBuilderHandler::setInputFile (QString f)
425 void mapBuilderHandler::setLoadMode (const LoadMode &lm)
430 bool mapBuilderHandler::readBranchAttr (const QXmlAttributes& a)
433 if (!readOOAttr(a)) return false;
435 if (!a.value( "scrolled").isEmpty() )
436 lastBranch->toggleScroll();
437 if (!a.value( "frameType").isEmpty() )
438 lastBranch->setFrameType (a.value("frameType"));
440 if (!a.value( "incImgV").isEmpty() )
442 if (a.value("incImgV")=="true")
443 lastBranch->setIncludeImagesVer(true);
445 lastBranch->setIncludeImagesVer(false);
447 if (!a.value( "incImgH").isEmpty() )
449 if (a.value("incImgH")=="true")
450 lastBranch->setIncludeImagesHor(true);
452 lastBranch->setIncludeImagesHor(false);
457 bool mapBuilderHandler::readOOAttr (const QXmlAttributes& a)
463 if (!a.value( "relPosX").isEmpty() )
465 if (!a.value( "relPosY").isEmpty() )
467 x=a.value("relPosX").toInt (&okx, 10);
468 y=a.value("relPosY").toInt (&oky, 10);
471 lastOO->setUseRelPos (true);
472 lastOO->move2RelPos (x,y);
475 return false; // Couldn't read relPos
478 if (!a.value( "absPosX").isEmpty() && loadMode==NewMap && branchDepth<2)
480 if (!a.value( "absPosY").isEmpty() )
482 x=a.value("absPosX").toInt (&okx, 10);
483 y=a.value("absPosY").toInt (&oky, 10);
487 return false; // Couldn't read absPos
490 if (!a.value( "url").isEmpty() )
491 lastOO->setURL (a.value ("url"));
492 if (!a.value( "vymLink").isEmpty() )
493 lastOO->setVymLink (a.value ("vymLink"));
494 if (!a.value( "hideInExport").isEmpty() )
495 if (a.value("hideInExport")=="true")
496 lastOO->setHideInExport(true);
498 if (!a.value( "hideLink").isEmpty())
500 if (a.value ("hideLink") =="true")
501 lastOO->setHideLinkUnselected(true);
503 lastOO->setHideLinkUnselected(false);
509 bool mapBuilderHandler::readNoteAttr (const QXmlAttributes& a)
510 { // only for backward compatibility (<1.4.6). Use htmlnote now.
513 if (!a.value( "href").isEmpty() )
516 fn=parseHREF(a.value ("href") );
518 QString s; // Reading a note
520 if ( !file.open( QIODevice::ReadOnly) )
522 qWarning ("mapBuilderHandler::readNoteAttr: Couldn't load "+fn);
525 QTextStream stream( &file );
527 while ( !stream.atEnd() ) {
528 lines += stream.readLine()+"\n";
531 // Convert to richtext
532 if ( !Q3StyleSheet::mightBeRichText( lines ) )
534 // Here we are workarounding the QT conversion method:
535 // convertFromPlainText does not generate valid xml, needed
536 // for the parser, but just <p> and <br> without closing tags.
537 // So we have to add those by ourselves
538 //lines=quotemeta (lines);
539 lines = Q3StyleSheet::convertFromPlainText( lines, Q3StyleSheetItem::WhiteSpaceNormal );
540 lines.replace ("<br>","<br />");
543 lines ="<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body>"+lines + "</p></body></html>";
546 if (!a.value( "fonthint").isEmpty() )
547 no.setFontHint(a.value ("fonthint") );
548 if (state == StateMapCenterNote)
551 lastBranch->setNote(no);
555 bool mapBuilderHandler::readFloatImageAttr (const QXmlAttributes& a)
559 //if (!readOOAttr(a)) return false;
561 if (!a.value( "useOrientation").isEmpty() )
563 if (a.value ("useOrientation") =="true")
564 lastFloat->setUseOrientation (true);
566 lastFloat->setUseOrientation (false);
568 if (!a.value( "href").isEmpty() )
571 if (!lastFloat->load (parseHREF(a.value ("href") ) ))
573 QMessageBox::warning( 0, "Warning: " ,
574 "Couldn't load float image\n"+parseHREF(a.value ("href") ));
575 lastBranch->removeFloatImage(((FloatImageObj*)(lastFloat)));
581 if (!a.value( "floatExport").isEmpty() )
583 // Only for compatibility. THis is not used since 1.7.11
584 if (a.value ("floatExport") =="true")
585 lastFloat->setFloatExport(true);
587 lastFloat->setFloatExport (false);
589 if (!a.value( "zPlane").isEmpty() )
590 lastFloat->setZ (a.value("zPlane").toInt ());
593 if (!a.value( "relPosX").isEmpty() )
595 if (!a.value( "relPosY").isEmpty() )
598 x=a.value("relPosX").toInt (&okx, 10);
599 y=a.value("relPosY").toInt (&oky, 10);
603 lastFloat->setRelPos (QPoint (x,y) );
604 // make sure floats in mapcenter are repositioned to relative pos
605 if (mc==lastBranch) mc->positionContents();
608 // Couldn't read relPos
613 if (!readOOAttr(a)) return false;
615 if (!a.value ("orgName").isEmpty() )
617 ((FloatImageObj*)(lastFloat))->setOriginalFilename (a.value("orgName"));
622 bool mapBuilderHandler::readXLinkAttr (const QXmlAttributes& a)
627 XLinkObj *xlo=new XLinkObj (mc->getCanvas());
628 if (!a.value( "color").isEmpty() )
630 col.setNamedColor(a.value("color"));
634 if (!a.value( "width").isEmpty() )
636 xlo->setWidth(a.value ("width").toInt (&okx, 10));
639 if (!a.value( "beginBranch").isEmpty() )
641 if (!a.value( "endBranch").isEmpty() )
643 LinkableMapObj *lmo=mc->findObjBySelect (a.value( "beginBranch"));
644 if (lmo && typeid (*lmo)==typeid (BranchObj))
646 xlo->setBegin ((BranchObj*)(lmo));
647 lmo=mc->findObjBySelect (a.value( "endBranch"));
648 if (lmo && typeid (*lmo)==typeid (BranchObj))
650 xlo->setEnd ((BranchObj*)(lmo));
654 success=true; // Not all branches there yet, no error
657 if (!success) delete (xlo);
661 bool mapBuilderHandler::readHtmlAttr (const QXmlAttributes& a)
663 for (int i=1; i<=a.count(); i++)
664 htmldata+=" "+a.localName(i-1)+"=\""+a.value(i-1)+"\"";
668 bool mapBuilderHandler::readSettingAttr (const QXmlAttributes& a)
670 if (!a.value( "key").isEmpty() )
672 if (!a.value( "value").isEmpty() )
673 settings.setLocalEntry (me->getDestPath(), a.value ("key"), a.value ("value"));