3 #include <qmessagebox.h>
5 #include <qstylesheet.h>
10 #include "linkablemapobj.h"
14 static BranchObj *lastBranch;
15 static FloatObj *lastFloat;
17 extern Settings settings;
19 mapBuilderHandler::mapBuilderHandler() {}
21 mapBuilderHandler::~mapBuilderHandler() {}
23 QString mapBuilderHandler::errorProtocol() { return errorProt; }
25 bool mapBuilderHandler::startDocument()
29 laststate = StateInit;
37 QString mapBuilderHandler::parseHREF(QString href)
39 QString type=href.section(":",0,0);
40 QString path=href.section(":",1,1);
41 if (!tmpDir.endsWith("/"))
42 return tmpDir + "/" + path;
47 bool mapBuilderHandler::startElement ( const QString&, const QString&,
48 const QString& eName, const QXmlAttributes& atts )
51 //cout << "startElement <"<<eName<<"> state="<<state <<" laststate="<<laststate<<" loadMode="<<loadMode<<endl;
52 if ( state == StateInit && (eName == "vymmap") )
55 if (!atts.value( "version").isEmpty() )
57 mc->setVersion(atts.value( "version" ));
58 if (!mc->checkVersion())
59 QMessageBox::warning( 0, "Warning: Version Problem" ,
60 "<h3>Map is newer than VYM</h3>"
61 "<p>The map you are just trying to load was "
62 "saved using vym " +atts.value("version")+". "
63 "The version of this vym is " __VYM_VERSION__
64 ". If you run into problems after pressing "
65 "the ok-button below, updating vym should help.");
70 if (!atts.value( "author").isEmpty() )
72 mc->setAuthor(atts.value( "author" ) );
74 if (!atts.value( "comment").isEmpty() )
76 mc->setComment (atts.value( "comment" ) );
78 if (!atts.value( "backgroundColor").isEmpty() )
80 col.setNamedColor(atts.value("backgroundColor"));
81 mc->getCanvas()->setBackgroundColor(col);
83 if (!atts.value( "linkColorHint").isEmpty() )
85 if (atts.value("linkColorHint")=="HeadingColor")
86 me->setLinkColorHint(HeadingColor);
88 me->setLinkColorHint(DefaultColor);
90 if (!atts.value( "linkStyle").isEmpty() )
92 QString s=atts.value("linkStyle");
94 me->setLinkStyle(StyleLine);
96 if (s=="StyleParabel")
97 me->setLinkStyle(StyleParabel);
99 if (s=="StylePolyLine")
100 me->setLinkStyle(StylePolyLine);
102 me->setLinkStyle(StylePolyParabel);
104 if (!atts.value( "linkColor").isEmpty() )
106 col.setNamedColor(atts.value("linkColor"));
107 me->setLinkColor(col);
109 if (!atts.value( "defXLinkColor").isEmpty() )
111 col.setNamedColor(atts.value("defXLinkColor"));
112 me->setDefXLinkColor(col);
114 if (!atts.value( "defXLinkWidth").isEmpty() )
116 me->setDefXLinkWidth(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 ,false );
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" && state == StateMap)
180 // This is used in vymparts, which have no mapcenter!
183 LinkableMapObj* lmo=me->getSelection();
186 // If a vym part is _loaded_ (not imported),
187 // selection==lmo==NULL
188 // Treat it like ImportAdd then...
192 if (lmo && (typeid(*lmo) == typeid(BranchObj) )
193 || (typeid(*lmo) == typeid(MapCenterObj) ) )
195 lastBranch=(BranchObj*)(lmo);
196 if (loadMode==ImportAdd)
198 lastBranch->addBranch();
199 lastBranch=lastBranch->getLastBranch();
205 readBranchAttr (atts);
206 } else if ( eName == "branch" && state == StateMapCenter)
210 lastBranch->addBranch();
211 lastBranch=lastBranch->getLastBranch();
212 readBranchAttr (atts);
213 } else if ( (eName=="standardflag" ||eName == "standardFlag") && state == StateBranch)
215 state=StateBranchStandardFlag;
216 } else if ( eName == "heading" && state == StateBranch)
218 state=StateBranchHeading;
219 if (!atts.value( "textColor").isEmpty() )
221 col.setNamedColor(atts.value("textColor"));
222 lastBranch->setColor(col ,false );
224 } else if ( eName == "note" && state == StateBranch)
226 state=StateBranchNote;
227 if (!readNoteAttr (atts) ) return false;
228 } else if ( eName == "htmlnote" && state == StateBranch)
233 if (!atts.value( "fonthint").isEmpty() )
234 no.setFontHint(atts.value ("fonthint") );
235 } else if ( eName == "floatimage" && state == StateBranch )
237 state=StateBranchFloatImage;
238 lastBranch->addFloatImage();
239 lastFloat=lastBranch->getLastFloatImage();
240 if (!readFloatImageAttr(atts)) return false;
241 } else if ( eName == "xlink" && state == StateBranch )
243 state=StateBranchXLink;
244 if (!readXLinkAttr (atts)) return false;
245 } else if ( eName == "branch" && state == StateBranch )
247 lastBranch->addBranch();
248 lastBranch=lastBranch->getLastBranch();
250 readBranchAttr (atts);
251 } else if ( eName == "html" && state == StateHtmlNote )
257 } else if ( state == StateHtml )
259 // accept all while in html mode,
264 return false; // Error
268 bool mapBuilderHandler::endElement ( const QString&, const QString&, const QString &eName)
270 // cout << "endElement </"<<eName<<"> state="<<state <<" laststate="<<laststate<<endl;
273 case StateMapSelect: state=StateMap; return true;
274 case StateMapSetting: state=StateMap; return true;
275 case StateMapCenter: state=StateMap; return true;
276 case StateMapCenterStandardFlag: state=StateMapCenter; return true;
277 case StateMapCenterHeading: state=StateMapCenter; return true;
278 case StateMapCenterNote: state=StateMapCenter; return true;
279 case StateMapCenterFloatImage: state=StateMapCenter; return true;
291 state=StateMapCenter;
293 lastBranch=(BranchObj*)(lastBranch->getParObj());
295 case StateBranchStandardFlag: state=StateBranch; return true;
296 case StateBranchHeading: state=StateBranch; return true;
297 case StateBranchNote: state=StateBranch; return true;
298 case StateBranchFloatImage: state=StateBranch; return true;
299 case StateBranchXLink: state=StateBranch; return true;
300 case StateHtmlNote: state=laststate; return true;
302 htmldata+="</"+eName+">";
306 htmldata.replace ("<br></br>","<br />");
307 no.setNote (htmldata);
308 lastBranch->setNote (no);
314 case StateMap: state=StateInit; return true;
316 // even for HTML includes, this should never be reached
321 bool mapBuilderHandler::characters ( const QString& ch)
323 //cout << "characters \""<<ch<<"\" state="<<state <<" laststate="<<laststate<<endl;
325 QString ch_org=quotemeta (ch);
326 QString ch_simplified=ch.simplifyWhiteSpace();
327 if ( ch_simplified.isEmpty() ) return true;
331 case StateInit: break;
332 case StateMap: break;
334 me->select(ch_simplified);
336 case StateMapSetting:break;
337 case StateMapCenter: break;
338 case StateMapCenterStandardFlag:
339 lastBranch->activateStandardFlag(ch_simplified);
341 case StateMapCenterHeading:
342 lastBranch->setHeading(ch_simplified);
344 case StateMapCenterNote:
345 lastBranch->setNote(ch_simplified);
347 case StateBranch: break;
348 case StateBranchStandardFlag:
349 lastBranch->activateStandardFlag(ch_simplified);
351 case StateBranchHeading:
352 lastBranch->setHeading(ch_simplified);
354 case StateBranchNote:
355 lastBranch->setNote(ch_simplified);
357 case StateBranchFloatImage: break;
358 case StateHtmlNote: break;
368 QString mapBuilderHandler::errorString()
370 return "the document is not in the VYM file format";
373 bool mapBuilderHandler::fatalError( const QXmlParseException& exception )
375 errorProt += QString( "fatal parsing error: %1 in line %2, column %3\n")
376 .arg( exception.message() )
377 .arg( exception.lineNumber() )
378 .arg( exception.columnNumber() );
380 return QXmlDefaultHandler::fatalError( exception );
383 void mapBuilderHandler::setMapEditor (MapEditor* e)
386 mc=me->getMapCenter();
389 void mapBuilderHandler::setTmpDir (QString tp)
394 void mapBuilderHandler::setLoadMode (const LoadMode &lm)
399 bool mapBuilderHandler::readBranchAttr (const QXmlAttributes& a)
403 if (!a.value( "absPosX").isEmpty() && loadMode==NewMap && branchDepth<2)
405 if (!a.value( "absPosY").isEmpty() )
407 x=a.value("absPosX").toInt (&okx, 10);
408 y=a.value("absPosY").toInt (&oky, 10);
410 lastBranch->move(x,y);
412 return false; // Couldn't read absPos
415 if (!a.value( "scrolled").isEmpty() )
416 lastBranch->toggleScroll();
417 if (!a.value( "url").isEmpty() )
418 lastBranch->setURL (a.value ("url"));
419 if (!a.value( "vymLink").isEmpty() )
420 lastBranch->setVymLink (a.value ("vymLink"));
421 if (!a.value( "frameType").isEmpty() )
422 lastBranch->setFrameType (a.value("frameType"));
426 bool mapBuilderHandler::readNoteAttr (const QXmlAttributes& a)
427 { // only for backward compatibility (<1.4.6). Use htmlnote now.
430 if (!a.value( "href").isEmpty() )
433 fn=parseHREF(a.value ("href") );
435 QString s; // Reading a note
437 if ( !file.open( IO_ReadOnly) )
439 qWarning ("mapBuilderHandler::readNoteAttr: Couldn't load "+fn);
442 QTextStream stream( &file );
444 while ( !stream.eof() ) {
445 lines += stream.readLine()+"\n";
448 // Convert to richtext
449 if ( !QStyleSheet::mightBeRichText( lines ) )
451 // Here we are workarounding the QT conversion method:
452 // convertFromPlainText does not generate valid xml, needed
453 // for the parser, but just <p> and <br> without closing tags.
454 // So we have to add those by ourselves
455 //lines=quotemeta (lines);
456 lines = QStyleSheet::convertFromPlainText( lines, QStyleSheetItem::WhiteSpaceNormal );
457 lines.replace ("<br>","<br />");
460 lines ="<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body>"+lines + "</p></body></html>";
463 if (!a.value( "fonthint").isEmpty() )
464 no.setFontHint(a.value ("fonthint") );
465 if (state == StateMapCenterNote)
468 lastBranch->setNote(no);
472 bool mapBuilderHandler::readFloatImageAttr (const QXmlAttributes& a)
474 if (!a.value( "useOrientation").isEmpty() )
476 if (a.value ("useOrientation") =="true")
477 lastFloat->setUseOrientation (true);
479 lastFloat->setUseOrientation (false);
481 if (!a.value( "href").isEmpty() )
484 if (!lastFloat->load (parseHREF(a.value ("href") ) ))
486 QMessageBox::warning( 0, "Warning: " ,
487 "Couldn't load float image\n"+parseHREF(a.value ("href") ));
488 lastBranch->removeFloatImage(((FloatImageObj*)(lastFloat)));
494 if (!a.value( "floatExport").isEmpty() )
496 if (a.value ("floatExpofrt") =="true")
497 lastFloat->setFloatExport (true);
499 lastFloat->setFloatExport (false);
501 if (!a.value( "zPlane").isEmpty() )
502 lastFloat->setZ (a.value("zPlane").toInt ());
505 if (!a.value( "relPosX").isEmpty() )
507 if (!a.value( "relPosY").isEmpty() )
510 x=a.value("relPosX").toInt (&okx, 10);
511 y=a.value("relPosY").toInt (&oky, 10);
513 lastFloat->setRelPos (QPoint (x,y) );
515 // Couldn't read relPos
522 bool mapBuilderHandler::readXLinkAttr (const QXmlAttributes& a)
526 XLinkObj *xlo=new XLinkObj (mc->getCanvas());
527 if (!a.value( "color").isEmpty() )
529 col.setNamedColor(a.value("color"));
533 if (!a.value( "width").isEmpty() )
535 xlo->setWidth(a.value ("width").toInt (&okx, 10));
538 if (!a.value( "beginBranch").isEmpty() )
540 if (!a.value( "endBranch").isEmpty() )
542 LinkableMapObj *lmo=mc->findObj (a.value( "beginBranch"));
543 if (lmo && typeid (*lmo)==typeid (BranchObj))
545 xlo->setBegin ((BranchObj*)(lmo));
546 lmo=mc->findObj (a.value( "endBranch"));
547 if (lmo && typeid (*lmo)==typeid (BranchObj))
549 xlo->setEnd ((BranchObj*)(lmo));
554 return true; // Not all branches there yet, no error
560 bool mapBuilderHandler::readHtmlAttr (const QXmlAttributes& a)
562 for (int i=1; i<=a.count(); i++)
563 htmldata+=" "+a.localName(i-1)+"=\""+a.value(i-1)+"\"";
567 bool mapBuilderHandler::readSettingAttr (const QXmlAttributes& a)
569 if (!a.value( "key").isEmpty() )
571 if (!a.value( "value").isEmpty() )
572 settings.setLocalEntry (me->getDestPath(), a.value ("key"), a.value ("value"));