# HG changeset patch # User insilmaril # Date 1185788835 0 # Node ID f342fa34658098dc29b635bdcaf936bedac7c94b # Parent 4b935d7e16712d6f83172a8df9f8a3dce9d0fa1c 1.9.4 New base class for XML based file parsing (vym & Freemind) diff -r 4b935d7e1671 -r f342fa346580 xml-vym.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xml-vym.cpp Mon Jul 30 09:47:15 2007 +0000 @@ -0,0 +1,686 @@ +#include "xml-vym.h" + +#include +#include +#include +#include + +#include "misc.h" +#include "settings.h" +#include "linkablemapobj.h" +#include "version.h" + +static BranchObj *lastBranch; +static FloatObj *lastFloat; +static OrnamentedObj *lastOO; + +extern Settings settings; +extern QString vymVersion; + +/* +parseVYMHandler::parseVYMHandler() {} + +parseVYMHandler::~parseVYMHandler() {} + +QString parseVYMHandler::errorProtocol() { return errorProt; } + +*/ + +bool parseVYMHandler::startDocument() +{ + errorProt = ""; + state = StateInit; + laststate = StateInit; + stateStack.clear(); + stateStack.append(StateInit); + branchDepth=0; + htmldata=""; + isVymPart=false; + return true; +} + + +/* +QString parseVYMHandler::parseHREF(QString href) +{ + QString type=href.section(":",0,0); + QString path=href.section(":",1,1); + if (!tmpDir.endsWith("/")) + return tmpDir + "/" + path; + else + return tmpDir + path; +} +*/ +bool parseVYMHandler::startElement ( const QString&, const QString&, + const QString& eName, const QXmlAttributes& atts ) +{ + QColor col; + /* Testing + cout << "startElement <"<< eName.ascii() + <<"> state="<Map is newer than VYM" + "

The map you are just trying to load was " + "saved using vym " +atts.value("version")+". " + "The version of this vym is " + vymVersion + + ". If you run into problems after pressing " + "the ok-button below, updating vym should help."); + else + mc->setVersion(atts.value( "version" )); + + } + if (loadMode==NewMap || + (loadMode==ImportReplace && me->getSelection()==mc)) + { + if (!atts.value( "author").isEmpty() ) + { + mc->setAuthor(atts.value( "author" ) ); + } + if (!atts.value( "comment").isEmpty() ) + { + mc->setComment (atts.value( "comment" ) ); + } + if (!atts.value( "backgroundColor").isEmpty() ) + { + col.setNamedColor(atts.value("backgroundColor")); + mc->getScene()->setBackgroundBrush(col); + } + if (!atts.value( "selectionColor").isEmpty() ) + { + col.setNamedColor(atts.value("selectionColor")); + me->setSelectionColor(col); + } + if (!atts.value( "linkColorHint").isEmpty() ) + { + if (atts.value("linkColorHint")=="HeadingColor") + me->setMapLinkColorHint(LinkableMapObj::HeadingColor); + else + me->setMapLinkColorHint(LinkableMapObj::DefaultColor); + } + if (!atts.value( "linkStyle").isEmpty() ) + { + me->setMapLinkStyle(atts.value("linkStyle")); + } + if (!atts.value( "linkColor").isEmpty() ) + { + col.setNamedColor(atts.value("linkColor")); + me->setMapDefLinkColor(col); + } + if (!atts.value( "defXLinkColor").isEmpty() ) + { + col.setNamedColor(atts.value("defXLinkColor")); + me->setMapDefXLinkColor(col); + } + if (!atts.value( "defXLinkWidth").isEmpty() ) + { + me->setMapDefXLinkWidth(atts.value("defXLinkWidth").toInt ()); + } + } + } else if ( eName == "select" && state == StateMap ) + { + state=StateMapSelect; + } else if ( eName == "setting" && state == StateMap ) + { + state=StateMapSetting; + if (loadMode==NewMap) + readSettingAttr (atts); + } else if ( eName == "mapcenter" && state == StateMap ) + { + state=StateMapCenter; + if (loadMode==NewMap) + { + // Really use the found mapcenter as MCO in a new map + lastBranch=mc; // avoid empty pointer + } else + { + // Treat the found mapcenter as a branch + // in an existing map + LinkableMapObj* lmo=me->getSelection(); + if (lmo && (typeid(*lmo) == typeid(BranchObj) ) + || (typeid(*lmo) == typeid(MapCenterObj) ) ) + { + lastBranch=(BranchObj*)lmo; + if (loadMode==ImportAdd) + { + lastBranch->addBranch(); + lastBranch=lastBranch->getLastBranch(); + } else + lastBranch->clear(); + } else + return false; + } + readBranchAttr (atts); + } else if ( + (eName == "standardflag" ||eName == "standardFlag") && + (state == StateMapCenter || state==StateBranch)) + { + state=StateStandardFlag; + } else if ( eName == "heading" && (state == StateMapCenter||state==StateBranch)) + { + laststate=state; + state=StateHeading; + if (!atts.value( "textColor").isEmpty() ) + { + col.setNamedColor(atts.value("textColor")); + lastBranch->setColor(col ); + } + } else if ( eName == "note" && + (state == StateMapCenter ||state==StateBranch)) + { // only for backward compatibility (<1.4.6). Use htmlnote now. + state=StateNote; + if (!readNoteAttr (atts) ) return false; + } else if ( eName == "htmlnote" && state == StateMapCenter) + { + laststate=state; + state=StateHtmlNote; + } else if ( eName == "floatimage" && + (state == StateMapCenter ||state==StateBranch)) + { + state=StateFloatImage; + lastBranch->addFloatImage(); + lastFloat=lastBranch->getLastFloatImage(); + if (!readFloatImageAttr(atts)) return false; + } else if ( (eName == "branch"||eName=="floatimage") && state == StateMap) + { + // This is used in vymparts, which have no mapcenter! + isVymPart=true; + LinkableMapObj* lmo=me->getSelection(); + if (!lmo) + { + // If a vym part is _loaded_ (not imported), + // selection==lmo==NULL + // Treat it like ImportAdd then... + loadMode=ImportAdd; + lmo=mc; + } + if (lmo && (typeid(*lmo) == typeid(BranchObj) ) + || (typeid(*lmo) == typeid(MapCenterObj) ) ) + { + lastBranch=(BranchObj*)(lmo); + if (eName=="branch") + { + state=StateBranch; + if (loadMode==ImportAdd) + { + lastBranch->addBranch(); + lastBranch=lastBranch->getLastBranch(); + + } else + lastBranch->clear(); + branchDepth=1; + readBranchAttr (atts); + } else if (eName=="floatimage") + { + state=StateFloatImage; + lastBranch->addFloatImage(); + lastFloat=lastBranch->getLastFloatImage(); + if (!readFloatImageAttr(atts)) return false; + } else return false; + } else return false; + } else if ( eName == "branch" && state == StateMapCenter) + { + state=StateBranch; + branchDepth=1; + lastBranch->addBranch(); + lastBranch=lastBranch->getLastBranch(); + readBranchAttr (atts); + } else if ( eName == "htmlnote" && state == StateBranch) + { + laststate=state; + state=StateHtmlNote; + no.clear(); + if (!atts.value( "fonthint").isEmpty() ) + no.setFontHint(atts.value ("fonthint") ); + } else if ( eName == "frame" && (state == StateBranch||state==StateMapCenter)) + { + laststate=state; + state=StateFrame; + if (!readFrameAttr(atts)) return false; + } else if ( eName == "xlink" && state == StateBranch ) + { + state=StateBranchXLink; + if (!readXLinkAttr (atts)) return false; + } else if ( eName == "branch" && state == StateBranch ) + { + lastBranch->addBranch(); + lastBranch=lastBranch->getLastBranch(); + branchDepth++; + readBranchAttr (atts); + } else if ( eName == "html" && state == StateHtmlNote ) + { + state=StateHtml; + htmldata="<"+eName; + readHtmlAttr(atts); + htmldata+=">"; + } else if ( state == StateHtml ) + { + // accept all while in html mode, + htmldata+="<"+eName; + readHtmlAttr(atts); + htmldata+=">"; + } else + return false; // Error + return true; +} + +bool parseVYMHandler::endElement ( const QString&, const QString&, const QString &eName) +{ + /* Testing + cout << "endElement state=" <"; + if (eName=="html") + { + state=StateHtmlNote; + htmldata.replace ("

","
"); + no.setNote (htmldata); + lastBranch->setNote (no); + } + break; + default: + break; + } + state=stateStack.takeLast(); + return true; +} + +bool parseVYMHandler::characters ( const QString& ch) +{ + //cout << "characters \""<"); + errorProt+=s; + } + return QXmlDefaultHandler::fatalError( exception ); +} + +void parseVYMHandler::setMapEditor (MapEditor* e) +{ + me=e; + mc=me->getMapCenter(); +} + +void parseVYMHandler::setTmpDir (QString tp) +{ + tmpDir=tp; +} + +void parseVYMHandler::setInputFile (QString f) +{ + inputFile=f; +} + +void parseVYMHandler::setLoadMode (const LoadMode &lm) +{ + loadMode=lm; +} +*/ +bool parseVYMHandler::readBranchAttr (const QXmlAttributes& a) +{ + lastOO=lastBranch; + if (!readOOAttr(a)) return false; + + if (!a.value( "scrolled").isEmpty() ) + lastBranch->toggleScroll(); + if (!a.value( "frameType").isEmpty() ) + lastOO->setFrameType (a.value("frameType")); //Compatibility 1.8.1 + + if (!a.value( "incImgV").isEmpty() ) + { + if (a.value("incImgV")=="true") + lastBranch->setIncludeImagesVer(true); + else + lastBranch->setIncludeImagesVer(false); + } + if (!a.value( "incImgH").isEmpty() ) + { + if (a.value("incImgH")=="true") + lastBranch->setIncludeImagesHor(true); + else + lastBranch->setIncludeImagesHor(false); + } + return true; +} + +bool parseVYMHandler::readFrameAttr (const QXmlAttributes& a) +{ + bool ok; + int x; + if (lastOO) + { + if (!a.value( "frameType").isEmpty() ) + lastOO->setFrameType (a.value("frameType")); + if (!a.value( "penColor").isEmpty() ) + lastOO->setFramePenColor (a.value("penColor")); + if (!a.value( "brushColor").isEmpty() ) + lastOO->setFrameBrushColor (a.value("brushColor")); + if (!a.value( "padding").isEmpty() ) + { + x=a.value("padding").toInt(&ok); + if (ok) lastOO->setFramePadding(x); + } + if (!a.value( "borderWidth").isEmpty() ) + { + x=a.value("borderWidth").toInt(&ok); + if (ok) lastOO->setFrameBorderWidth(x); + } + } + return true; +} + +bool parseVYMHandler::readOOAttr (const QXmlAttributes& a) +{ + if (lastOO) + { + bool okx,oky; + int x,y; + if (!a.value( "relPosX").isEmpty() ) + { + if (!a.value( "relPosY").isEmpty() ) + { + x=a.value("relPosX").toInt (&okx, 10); + y=a.value("relPosY").toInt (&oky, 10); + if (okx && oky ) + { + lastOO->setUseRelPos (true); + lastOO->move2RelPos (x,y); + } + else + return false; // Couldn't read relPos + } + } + if (!a.value( "absPosX").isEmpty() && loadMode==NewMap && branchDepth<2) + { + if (!a.value( "absPosY").isEmpty() ) + { + x=a.value("absPosX").toInt (&okx, 10); + y=a.value("absPosY").toInt (&oky, 10); + if (okx && oky ) + lastOO->move(x,y); + else + return false; // Couldn't read absPos + } + } + if (!a.value( "id").isEmpty() ) + lastOO->setID (a.value ("id")); + if (!a.value( "url").isEmpty() ) + lastOO->setURL (a.value ("url")); + if (!a.value( "vymLink").isEmpty() ) + lastOO->setVymLink (a.value ("vymLink")); + if (!a.value( "hideInExport").isEmpty() ) + if (a.value("hideInExport")=="true") + lastOO->setHideInExport(true); + + if (!a.value( "hideLink").isEmpty()) + { + if (a.value ("hideLink") =="true") + lastOO->setHideLinkUnselected(true); + else + lastOO->setHideLinkUnselected(false); + } + } + return true; +} + +bool parseVYMHandler::readNoteAttr (const QXmlAttributes& a) +{ // only for backward compatibility (<1.4.6). Use htmlnote now. + no.clear(); + QString fn; + if (!a.value( "href").isEmpty() ) + { + // Load note + fn=parseHREF(a.value ("href") ); + QFile file (fn); + QString s; // Reading a note + + if ( !file.open( QIODevice::ReadOnly) ) + { + qWarning ("parseVYMHandler::readNoteAttr: Couldn't load "+fn); + return false; + } + QTextStream stream( &file ); + QString lines; + while ( !stream.atEnd() ) { + lines += stream.readLine()+"\n"; + } + file.close(); + + lines =""+lines + "

"; + no.setNote (lines); + } + if (!a.value( "fonthint").isEmpty() ) + no.setFontHint(a.value ("fonthint") ); + lastBranch->setNote(no); + return true; +} + +bool parseVYMHandler::readFloatImageAttr (const QXmlAttributes& a) +{ + lastOO=lastFloat; + + //if (!readOOAttr(a)) return false; + + if (!a.value( "useOrientation").isEmpty() ) + { + if (a.value ("useOrientation") =="true") + lastFloat->setUseOrientation (true); + else + lastFloat->setUseOrientation (false); + } + if (!a.value( "href").isEmpty() ) + { + // Load FloatImage + if (!lastFloat->load (parseHREF(a.value ("href") ) )) + { + QMessageBox::warning( 0, "Warning: " , + "Couldn't load float image\n"+parseHREF(a.value ("href") )); + lastBranch->removeFloatImage(((FloatImageObj*)(lastFloat))); + lastFloat=NULL; + return true; + } + + } + if (!a.value( "floatExport").isEmpty() ) + { + // Only for compatibility. THis is not used since 1.7.11 + if (a.value ("floatExport") =="true") + lastFloat->setFloatExport(true); + else + lastFloat->setFloatExport (false); + } + if (!a.value( "zPlane").isEmpty() ) + lastFloat->setZValue (a.value("zPlane").toInt ()); + int x,y; + bool okx,oky; + if (!a.value( "relPosX").isEmpty() ) + { + if (!a.value( "relPosY").isEmpty() ) + { + // read relPos + x=a.value("relPosX").toInt (&okx, 10); + y=a.value("relPosY").toInt (&oky, 10); + if (okx && oky) + + { + lastFloat->setRelPos (QPoint (x,y) ); + // make sure floats in mapcenter are repositioned to relative pos + if (mc==lastBranch) mc->positionContents(); + } + else + // Couldn't read relPos + return false; + } + } + + if (!readOOAttr(a)) return false; + + if (!a.value ("orgName").isEmpty() ) + { + ((FloatImageObj*)(lastFloat))->setOriginalFilename (a.value("orgName")); + } + return true; +} + +bool parseVYMHandler::readXLinkAttr (const QXmlAttributes& a) +{ + QColor col; + bool okx; + bool success=false; + XLinkObj *xlo=new XLinkObj (mc->getScene()); + if (!a.value( "color").isEmpty() ) + { + col.setNamedColor(a.value("color")); + xlo->setColor (col); + } + + if (!a.value( "width").isEmpty() ) + { + xlo->setWidth(a.value ("width").toInt (&okx, 10)); + } + + // Connecting by select string for compatibility with version < 1.8.76 + if (!a.value( "beginBranch").isEmpty() ) + { + if (!a.value( "endBranch").isEmpty() ) + { + LinkableMapObj *lmo=mc->findObjBySelect (a.value( "beginBranch")); + if (lmo && typeid (*lmo)==typeid (BranchObj)) + { + xlo->setBegin ((BranchObj*)lmo); + lmo=mc->findObjBySelect (a.value( "endBranch")); + if (lmo && typeid (*lmo)==typeid (BranchObj)) + { + xlo->setEnd ((BranchObj*)(lmo)); + xlo->activate(); + } + } + success=true; // Not all branches there yet, no error + } + } + + // object ID is used starting in version 1.8.76 + if (!a.value( "beginID").isEmpty() ) + { + if (!a.value( "endID").isEmpty() ) + { + LinkableMapObj *lmo=mc->findID (a.value( "beginBranch")); + if (lmo && typeid (*lmo)==typeid (BranchObj)) + { + xlo->setBegin ((BranchObj*)lmo); + lmo=mc->findID (a.value( "endID")); + if (lmo && typeid (*lmo)==typeid (BranchObj)) + { + xlo->setEnd ((BranchObj*)(lmo)); + xlo->activate(); + } + } + success=true; // Not all branches there yet, no error + } + } + if (!success) delete (xlo); + return success; +} + +bool parseVYMHandler::readHtmlAttr (const QXmlAttributes& a) +{ + for (int i=1; i<=a.count(); i++) + htmldata+=" "+a.localName(i-1)+"=\""+a.value(i-1)+"\""; + return true; +} + +bool parseVYMHandler::readSettingAttr (const QXmlAttributes& a) +{ + if (!a.value( "key").isEmpty() ) + { + if (!a.value( "value").isEmpty() ) + settings.setLocalEntry (me->getDestPath(), a.value ("key"), a.value ("value")); + else + return false; + + } else + return false; + + return true; +}