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 )
54 //cout << "startElement <"<<eName<<"> state="<<state <<" laststate="<<laststate<<" loadMode="<<loadMode<<endl;
55 if ( state == StateInit && (eName == "vymmap") )
58 if (!atts.value( "version").isEmpty() )
60 mc->setVersion(atts.value( "version" ));
61 if (!mc->checkVersion())
62 QMessageBox::warning( 0, "Warning: Version Problem" ,
63 "<h3>Map is newer than VYM</h3>"
64 "<p>The map you are just trying to load was "
65 "saved using vym " +atts.value("version")+". "
66 "The version of this vym is " __VYM_VERSION
67 ". If you run into problems after pressing "
68 "the ok-button below, updating vym should help.");
73 if (!atts.value( "author").isEmpty() )
75 mc->setAuthor(atts.value( "author" ) );
77 if (!atts.value( "comment").isEmpty() )
79 mc->setComment (atts.value( "comment" ) );
81 if (!atts.value( "backgroundColor").isEmpty() )
83 col.setNamedColor(atts.value("backgroundColor"));
84 mc->getCanvas()->setBackgroundColor(col);
86 if (!atts.value( "linkColorHint").isEmpty() )
88 if (atts.value("linkColorHint")=="HeadingColor")
89 me->setLinkColorHint(HeadingColor);
91 me->setLinkColorHint(DefaultColor);
93 if (!atts.value( "linkStyle").isEmpty() )
95 QString s=atts.value("linkStyle");
97 me->setLinkStyle(StyleLine);
99 if (s=="StyleParabel")
100 me->setLinkStyle(StyleParabel);
102 if (s=="StylePolyLine")
103 me->setLinkStyle(StylePolyLine);
105 me->setLinkStyle(StylePolyParabel);
107 if (!atts.value( "linkColor").isEmpty() )
109 col.setNamedColor(atts.value("linkColor"));
110 me->setLinkColor(col);
112 if (!atts.value( "defXLinkColor").isEmpty() )
114 col.setNamedColor(atts.value("defXLinkColor"));
115 me->setDefXLinkColor(col);
117 if (!atts.value( "defXLinkWidth").isEmpty() )
119 me->setDefXLinkWidth(atts.value("defXLinkWidth").toInt ());
122 } else if ( eName == "select" && state == StateMap )
124 state=StateMapSelect;
125 } else if ( eName == "setting" && state == StateMap )
127 state=StateMapSetting;
128 if (loadMode==NewMap)
129 readSettingAttr (atts);
130 } else if ( eName == "mapcenter" && state == StateMap )
132 state=StateMapCenter;
133 if (loadMode==NewMap)
135 // Really use the found mapcenter as MCO in a new map
136 lastBranch=mc; // avoid empty pointer
139 // Treat the found mapcenter as a branch
140 // in an existing map
141 LinkableMapObj* lmo=me->getSelection();
142 if (lmo && (typeid(*lmo) == typeid(BranchObj) )
143 || (typeid(*lmo) == typeid(MapCenterObj) ) )
145 lastBranch=(BranchObj*)lmo;
146 if (loadMode==ImportAdd)
148 lastBranch->addBranch();
149 lastBranch=lastBranch->getLastBranch();
155 readBranchAttr (atts);
156 } else if ( (eName == "standardflag" ||eName == "standardFlag") && state == StateMapCenter)
158 state=StateMapCenterStandardFlag;
159 } else if ( eName == "heading" && state == StateMapCenter)
161 state=StateMapCenterHeading;
162 if (!atts.value( "textColor").isEmpty() )
164 col.setNamedColor(atts.value("textColor"));
165 lastBranch->setColor(col );
167 } else if ( eName == "note" && state == StateMapCenter)
168 { // only for backward compatibility (<1.4.6). Use htmlnote now.
169 state=StateMapCenterNote;
170 if (!readNoteAttr (atts) ) return false;
171 } else if ( eName == "htmlnote" && state == StateMapCenter)
175 } else if ( eName == "floatimage" && state == StateMapCenter )
177 state=StateMapCenterFloatImage;
178 lastBranch->addFloatImage();
179 lastFloat=lastBranch->getLastFloatImage();
180 if (!readFloatImageAttr(atts)) return false;
181 } else if ( (eName == "branch"||eName=="floatimage") && state == StateMap)
183 // This is used in vymparts, which have no mapcenter!
185 LinkableMapObj* lmo=me->getSelection();
188 // If a vym part is _loaded_ (not imported),
189 // selection==lmo==NULL
190 // Treat it like ImportAdd then...
194 if (lmo && (typeid(*lmo) == typeid(BranchObj) )
195 || (typeid(*lmo) == typeid(MapCenterObj) ) )
197 lastBranch=(BranchObj*)(lmo);
201 if (loadMode==ImportAdd)
203 lastBranch->addBranch();
204 lastBranch=lastBranch->getLastBranch();
209 readBranchAttr (atts);
210 } else if (eName=="floatimage")
212 state=StateFloatImage;
213 lastBranch->addFloatImage();
214 lastFloat=lastBranch->getLastFloatImage();
215 if (!readFloatImageAttr(atts)) return false;
218 } else if ( eName == "branch" && state == StateMapCenter)
222 lastBranch->addBranch();
223 lastBranch=lastBranch->getLastBranch();
224 readBranchAttr (atts);
225 } else if ( (eName=="standardflag" ||eName == "standardFlag") && state == StateBranch)
227 state=StateBranchStandardFlag;
228 } else if ( eName == "heading" && state == StateBranch)
230 state=StateBranchHeading;
231 if (!atts.value( "textColor").isEmpty() )
233 col.setNamedColor(atts.value("textColor"));
234 lastBranch->setColor(col );
236 } else if ( eName == "note" && state == StateBranch)
238 state=StateBranchNote;
239 if (!readNoteAttr (atts) ) return false;
240 } else if ( eName == "htmlnote" && state == StateBranch)
245 if (!atts.value( "fonthint").isEmpty() )
246 no.setFontHint(atts.value ("fonthint") );
247 } else if ( eName == "floatimage" && state == StateBranch )
249 state=StateBranchFloatImage;
250 lastBranch->addFloatImage();
251 lastFloat=lastBranch->getLastFloatImage();
252 if (!readFloatImageAttr(atts)) return false;
253 } else if ( eName == "xlink" && state == StateBranch )
255 state=StateBranchXLink;
256 if (!readXLinkAttr (atts)) return false;
257 } else if ( eName == "branch" && state == StateBranch )
259 lastBranch->addBranch();
260 lastBranch=lastBranch->getLastBranch();
262 readBranchAttr (atts);
263 } else if ( eName == "html" && state == StateHtmlNote )
269 } else if ( state == StateHtml )
271 // accept all while in html mode,
276 return false; // Error
280 bool mapBuilderHandler::endElement ( const QString&, const QString&, const QString &eName)
282 // cout << "endElement </"<<eName<<"> state="<<state <<" laststate="<<laststate<<endl;
285 case StateMapSelect: state=StateMap; return true;
286 case StateMapSetting: state=StateMap; return true;
287 case StateMapCenter: state=StateMap; return true;
288 case StateMapCenterStandardFlag: state=StateMapCenter; return true;
289 case StateMapCenterHeading: state=StateMapCenter; return true;
290 case StateMapCenterNote: state=StateMapCenter; return true;
291 case StateMapCenterFloatImage: state=StateMapCenter; return true;
292 case StateFloatImage: state=StateMap; return true;
304 state=StateMapCenter;
306 lastBranch=(BranchObj*)(lastBranch->getParObj());
308 case StateBranchStandardFlag: state=StateBranch; return true;
309 case StateBranchHeading: state=StateBranch; return true;
310 case StateBranchNote: state=StateBranch; return true;
311 case StateBranchFloatImage: state=StateBranch; return true;
312 case StateBranchXLink: state=StateBranch; return true;
313 case StateHtmlNote: state=laststate; return true;
315 htmldata+="</"+eName+">";
319 htmldata.replace ("<br></br>","<br />");
320 no.setNote (htmldata);
321 lastBranch->setNote (no);
327 case StateMap: state=StateInit; return true;
329 // even for HTML includes, this should never be reached
334 bool mapBuilderHandler::characters ( const QString& ch)
336 //cout << "characters \""<<ch<<"\" state="<<state <<" laststate="<<laststate<<endl;
338 QString ch_org=quotemeta (ch);
339 QString ch_simplified=ch.simplifyWhiteSpace();
340 if ( ch_simplified.isEmpty() ) return true;
344 case StateInit: break;
345 case StateMap: break;
347 me->select(ch_simplified);
349 case StateMapSetting:break;
350 case StateMapCenter: break;
351 case StateMapCenterStandardFlag:
352 lastBranch->activateStandardFlag(ch_simplified);
354 case StateMapCenterHeading:
355 lastBranch->setHeading(ch_simplified);
357 case StateMapCenterNote:
358 lastBranch->setNote(ch_simplified);
360 case StateBranch: break;
361 case StateBranchStandardFlag:
362 lastBranch->activateStandardFlag(ch_simplified);
364 case StateBranchHeading:
365 lastBranch->setHeading(ch_simplified);
367 case StateBranchNote:
368 lastBranch->setNote(ch_simplified);
370 case StateBranchFloatImage: break;
371 case StateHtmlNote: break;
381 QString mapBuilderHandler::errorString()
383 return "the document is not in the VYM file format";
386 bool mapBuilderHandler::fatalError( const QXmlParseException& exception )
388 errorProt += QString( "Fatal parsing error: %1 in line %2, column %3\n")
389 .arg( exception.message() )
390 .arg( exception.lineNumber() )
391 .arg( exception.columnNumber() );
392 // Try to read the bogus line
393 errorProt+=QString("File is: %1\n").arg(inputFile);
395 if (loadStringFromDisk (inputFile,s))
397 QStringList sl=QStringList::split ("\n",s);
399 QStringList::Iterator it = sl.begin();
400 while (i<exception.lineNumber()-1)
406 s.insert (exception.columnNumber()-1,"<ERROR>");
409 return QXmlDefaultHandler::fatalError( exception );
412 void mapBuilderHandler::setMapEditor (MapEditor* e)
415 mc=me->getMapCenter();
418 void mapBuilderHandler::setTmpDir (QString tp)
423 void mapBuilderHandler::setInputFile (QString f)
428 void mapBuilderHandler::setLoadMode (const LoadMode &lm)
433 bool mapBuilderHandler::readBranchAttr (const QXmlAttributes& a)
436 if (!readOOAttr(a)) return false;
438 if (!a.value( "scrolled").isEmpty() )
439 lastBranch->toggleScroll();
440 if (!a.value( "frameType").isEmpty() )
441 lastBranch->setFrameType (a.value("frameType"));
443 if (!a.value( "incImgV").isEmpty() )
445 if (a.value("incImgV")=="true")
446 lastBranch->setIncludeImagesVer(true);
448 lastBranch->setIncludeImagesVer(false);
450 if (!a.value( "incImgH").isEmpty() )
452 if (a.value("incImgH")=="true")
453 lastBranch->setIncludeImagesHor(true);
455 lastBranch->setIncludeImagesHor(false);
460 bool mapBuilderHandler::readOOAttr (const QXmlAttributes& a)
466 if (!a.value( "absPosX").isEmpty() && loadMode==NewMap && branchDepth<2)
468 if (!a.value( "absPosY").isEmpty() )
470 x=a.value("absPosX").toInt (&okx, 10);
471 y=a.value("absPosY").toInt (&oky, 10);
475 return false; // Couldn't read absPos
478 if (!a.value( "url").isEmpty() )
479 lastOO->setURL (a.value ("url"));
480 if (!a.value( "vymLink").isEmpty() )
481 lastOO->setVymLink (a.value ("vymLink"));
482 if (!a.value( "hideInExport").isEmpty() )
483 if (a.value("hideInExport")=="true")
484 lastOO->setHideInExport(true);
486 if (!a.value( "hideLink").isEmpty())
488 if (a.value ("hideLink") =="true")
489 lastOO->setHideLinkUnselected(true);
491 lastOO->setHideLinkUnselected(false);
497 bool mapBuilderHandler::readNoteAttr (const QXmlAttributes& a)
498 { // only for backward compatibility (<1.4.6). Use htmlnote now.
501 if (!a.value( "href").isEmpty() )
504 fn=parseHREF(a.value ("href") );
506 QString s; // Reading a note
508 if ( !file.open( QIODevice::ReadOnly) )
510 qWarning ("mapBuilderHandler::readNoteAttr: Couldn't load "+fn);
513 QTextStream stream( &file );
515 while ( !stream.atEnd() ) {
516 lines += stream.readLine()+"\n";
519 // Convert to richtext
520 if ( !Q3StyleSheet::mightBeRichText( lines ) )
522 // Here we are workarounding the QT conversion method:
523 // convertFromPlainText does not generate valid xml, needed
524 // for the parser, but just <p> and <br> without closing tags.
525 // So we have to add those by ourselves
526 //lines=quotemeta (lines);
527 lines = Q3StyleSheet::convertFromPlainText( lines, Q3StyleSheetItem::WhiteSpaceNormal );
528 lines.replace ("<br>","<br />");
531 lines ="<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body>"+lines + "</p></body></html>";
534 if (!a.value( "fonthint").isEmpty() )
535 no.setFontHint(a.value ("fonthint") );
536 if (state == StateMapCenterNote)
539 lastBranch->setNote(no);
543 bool mapBuilderHandler::readFloatImageAttr (const QXmlAttributes& a)
547 //if (!readOOAttr(a)) return false;
549 if (!a.value( "useOrientation").isEmpty() )
551 if (a.value ("useOrientation") =="true")
552 lastFloat->setUseOrientation (true);
554 lastFloat->setUseOrientation (false);
556 if (!a.value( "href").isEmpty() )
559 if (!lastFloat->load (parseHREF(a.value ("href") ) ))
561 QMessageBox::warning( 0, "Warning: " ,
562 "Couldn't load float image\n"+parseHREF(a.value ("href") ));
563 lastBranch->removeFloatImage(((FloatImageObj*)(lastFloat)));
569 if (!a.value( "floatExport").isEmpty() )
571 // Only for compatibility. THis is not used since 1.7.11
572 if (a.value ("floatExport") =="true")
573 lastFloat->setFloatExport(true);
575 lastFloat->setFloatExport (false);
577 if (!a.value( "zPlane").isEmpty() )
578 lastFloat->setZ (a.value("zPlane").toInt ());
581 if (!a.value( "relPosX").isEmpty() )
583 if (!a.value( "relPosY").isEmpty() )
586 x=a.value("relPosX").toInt (&okx, 10);
587 y=a.value("relPosY").toInt (&oky, 10);
591 lastFloat->setRelPos (QPoint (x,y) );
592 // make sure floats in mapcenter are repositioned to relative pos
593 if (mc==lastBranch) mc->positionContents();
596 // Couldn't read relPos
601 if (!readOOAttr(a)) return false;
603 if (!a.value ("orgName").isEmpty() )
605 ((FloatImageObj*)(lastFloat))->setOriginalFilename (a.value("orgName"));
610 bool mapBuilderHandler::readXLinkAttr (const QXmlAttributes& a)
615 XLinkObj *xlo=new XLinkObj (mc->getCanvas());
616 if (!a.value( "color").isEmpty() )
618 col.setNamedColor(a.value("color"));
622 if (!a.value( "width").isEmpty() )
624 xlo->setWidth(a.value ("width").toInt (&okx, 10));
627 if (!a.value( "beginBranch").isEmpty() )
629 if (!a.value( "endBranch").isEmpty() )
631 LinkableMapObj *lmo=mc->findObjBySelect (a.value( "beginBranch"));
632 if (lmo && typeid (*lmo)==typeid (BranchObj))
634 xlo->setBegin ((BranchObj*)(lmo));
635 lmo=mc->findObjBySelect (a.value( "endBranch"));
636 if (lmo && typeid (*lmo)==typeid (BranchObj))
638 xlo->setEnd ((BranchObj*)(lmo));
642 success=true; // Not all branches there yet, no error
645 if (!success) delete (xlo);
649 bool mapBuilderHandler::readHtmlAttr (const QXmlAttributes& a)
651 for (int i=1; i<=a.count(); i++)
652 htmldata+=" "+a.localName(i-1)+"=\""+a.value(i-1)+"\"";
656 bool mapBuilderHandler::readSettingAttr (const QXmlAttributes& a)
658 if (!a.value( "key").isEmpty() )
660 if (!a.value( "value").isEmpty() )
661 settings.setLocalEntry (me->getDestPath(), a.value ("key"), a.value ("value"));