insilmaril@576: #include "xml-vym.h" insilmaril@576: insilmaril@576: #include insilmaril@576: #include insilmaril@576: #include insilmaril@576: #include insilmaril@611: #include insilmaril@576: insilmaril@749: #include "branchitem.h" insilmaril@576: #include "misc.h" insilmaril@576: #include "settings.h" insilmaril@576: #include "linkablemapobj.h" insilmaril@742: #include "mainwindow.h" insilmaril@576: #include "version.h" insilmaril@790: #include "xlinkitem.h" insilmaril@576: insilmaril@576: insilmaril@742: extern Main *mainWindow; insilmaril@576: extern Settings settings; insilmaril@576: extern QString vymVersion; insilmaril@576: insilmaril@576: bool parseVYMHandler::startDocument() insilmaril@576: { insilmaril@576: errorProt = ""; insilmaril@576: state = StateInit; insilmaril@576: laststate = StateInit; insilmaril@576: stateStack.clear(); insilmaril@576: stateStack.append(StateInit); insilmaril@576: htmldata=""; insilmaril@576: isVymPart=false; insilmaril@821: useProgress=false; insilmaril@576: return true; insilmaril@576: } insilmaril@576: insilmaril@576: bool parseVYMHandler::startElement ( const QString&, const QString&, insilmaril@576: const QString& eName, const QXmlAttributes& atts ) insilmaril@576: { insilmaril@576: QColor col; insilmaril@576: /* Testing insilmaril@660: cout << "startElement <"<< qPrintable(eName) insilmaril@576: <<"> state="<clear(); insilmaril@776: lastBranch=NULL; insilmaril@647: insilmaril@576: if (!atts.value( "author").isEmpty() ) insilmaril@647: model->setAuthor(atts.value( "author" ) ); insilmaril@576: if (!atts.value( "comment").isEmpty() ) insilmaril@647: model->setComment (atts.value( "comment" ) ); insilmaril@749: if (!atts.value( "branchCount").isEmpty() ) insilmaril@742: { insilmaril@749: branchesTotal=atts.value("branchCount").toInt(); insilmaril@742: if (branchesTotal>10) insilmaril@742: { insilmaril@821: useProgress=true; insilmaril@742: mainWindow->setProgressMaximum (branchesTotal); insilmaril@742: } insilmaril@821: } insilmaril@742: insilmaril@576: if (!atts.value( "backgroundColor").isEmpty() ) insilmaril@576: { insilmaril@576: col.setNamedColor(atts.value("backgroundColor")); insilmaril@647: model->getScene()->setBackgroundBrush(col); insilmaril@576: } insilmaril@576: if (!atts.value( "selectionColor").isEmpty() ) insilmaril@576: { insilmaril@576: col.setNamedColor(atts.value("selectionColor")); insilmaril@721: model->setSelectionColor(col); insilmaril@576: } insilmaril@576: if (!atts.value( "linkColorHint").isEmpty() ) insilmaril@576: { insilmaril@576: if (atts.value("linkColorHint")=="HeadingColor") insilmaril@721: model->setMapLinkColorHint(LinkableMapObj::HeadingColor); insilmaril@576: else insilmaril@721: model->setMapLinkColorHint(LinkableMapObj::DefaultColor); insilmaril@576: } insilmaril@576: if (!atts.value( "linkStyle").isEmpty() ) insilmaril@721: model->setMapLinkStyle(atts.value("linkStyle")); insilmaril@576: if (!atts.value( "linkColor").isEmpty() ) insilmaril@576: { insilmaril@576: col.setNamedColor(atts.value("linkColor")); insilmaril@721: model->setMapDefLinkColor(col); insilmaril@576: } insilmaril@576: if (!atts.value( "defXLinkColor").isEmpty() ) insilmaril@576: { insilmaril@576: col.setNamedColor(atts.value("defXLinkColor")); insilmaril@721: model->setMapDefXLinkColor(col); insilmaril@576: } insilmaril@576: if (!atts.value( "defXLinkWidth").isEmpty() ) insilmaril@721: model->setMapDefXLinkWidth(atts.value("defXLinkWidth").toInt ()); insilmaril@837: if (!atts.value( "mapZoomFactor").isEmpty() ) insilmaril@837: model->setMapZoomFactor(atts.value("mapZoomFactor").toDouble()); insilmaril@576: } insilmaril@727: // Check version insilmaril@727: if (!atts.value( "version").isEmpty() ) insilmaril@727: { insilmaril@727: if (!checkVersion(atts.value("version"))) insilmaril@727: QMessageBox::warning( 0, "Warning: Version Problem" , insilmaril@727: "

Map is newer than VYM

" insilmaril@727: "

The map you are just trying to load was " insilmaril@727: "saved using vym " +atts.value("version")+". " insilmaril@727: "The version of this vym is " + vymVersion + insilmaril@727: ". If you run into problems after pressing " insilmaril@727: "the ok-button below, updating vym should help."); insilmaril@727: else insilmaril@727: model->setVersion(atts.value( "version" )); insilmaril@727: insilmaril@727: } insilmaril@727: insilmaril@576: } else if ( eName == "select" && state == StateMap ) insilmaril@576: { insilmaril@576: state=StateMapSelect; insilmaril@576: } else if ( eName == "setting" && state == StateMap ) insilmaril@576: { insilmaril@576: state=StateMapSetting; insilmaril@576: if (loadMode==NewMap) insilmaril@576: readSettingAttr (atts); insilmaril@576: } else if ( eName == "mapcenter" && state == StateMap ) insilmaril@576: { insilmaril@576: state=StateMapCenter; insilmaril@576: if (loadMode==NewMap) insilmaril@576: { insilmaril@576: // Really use the found mapcenter as MCO in a new map insilmaril@776: lastBranch=model->createMapCenter(); insilmaril@576: } else insilmaril@576: { insilmaril@576: // Treat the found mapcenter as a branch insilmaril@576: // in an existing map insilmaril@795: BranchItem *bi=model->getSelectedBranch(); insilmaril@753: if (bi) insilmaril@576: { insilmaril@776: lastBranch=bi; insilmaril@576: if (loadMode==ImportAdd) insilmaril@576: { insilmaril@776: lastBranch=model->createBranch(lastBranch); insilmaril@753: } //else insilmaril@795: model->clearItem(lastBranch); insilmaril@576: } else insilmaril@788: // add mapCenter without parent insilmaril@788: lastBranch=model->createMapCenter(); insilmaril@788: } insilmaril@576: readBranchAttr (atts); insilmaril@576: } else if ( insilmaril@576: (eName == "standardflag" ||eName == "standardFlag") && insilmaril@576: (state == StateMapCenter || state==StateBranch)) insilmaril@576: { insilmaril@576: state=StateStandardFlag; insilmaril@576: } else if ( eName == "heading" && (state == StateMapCenter||state==StateBranch)) insilmaril@576: { insilmaril@576: laststate=state; insilmaril@576: state=StateHeading; insilmaril@576: if (!atts.value( "textColor").isEmpty() ) insilmaril@576: { insilmaril@576: col.setNamedColor(atts.value("textColor")); insilmaril@776: lastBranch->setHeadingColor(col ); insilmaril@576: } insilmaril@576: } else if ( eName == "note" && insilmaril@576: (state == StateMapCenter ||state==StateBranch)) insilmaril@576: { // only for backward compatibility (<1.4.6). Use htmlnote now. insilmaril@576: state=StateNote; insilmaril@576: if (!readNoteAttr (atts) ) return false; insilmaril@576: } else if ( eName == "htmlnote" && state == StateMapCenter) insilmaril@576: { insilmaril@576: laststate=state; insilmaril@576: state=StateHtmlNote; insilmaril@576: } else if ( eName == "floatimage" && insilmaril@576: (state == StateMapCenter ||state==StateBranch)) insilmaril@576: { insilmaril@776: state=StateImage; insilmaril@776: lastImage=model->createImage(lastBranch); insilmaril@776: if (!readImageAttr(atts)) return false; insilmaril@576: } else if ( (eName == "branch"||eName=="floatimage") && state == StateMap) insilmaril@576: { insilmaril@795: // This is used in vymparts, which have no mapcenter or for undo insilmaril@576: isVymPart=true; insilmaril@795: TreeItem *ti=model->getSelectedItem(); insilmaril@753: if (!ti) insilmaril@576: { insilmaril@576: // If a vym part is _loaded_ (not imported), insilmaril@576: // selection==lmo==NULL insilmaril@576: // Treat it like ImportAdd then... insilmaril@576: loadMode=ImportAdd; insilmaril@746: // FIXME-3 lmo=model->first()->getLMO(); insilmaril@741: // Do we really have no MCO when loading????? insilmaril@741: cout << "xml-vym aborted\n"; insilmaril@795: return false; insilmaril@576: } insilmaril@753: if (ti && ti->isBranchLikeType() ) insilmaril@576: { insilmaril@776: lastBranch=(BranchItem*)ti; insilmaril@576: if (eName=="branch") insilmaril@576: { insilmaril@576: state=StateBranch; insilmaril@576: if (loadMode==ImportAdd) insilmaril@576: { insilmaril@776: lastBranch=model->createBranch(lastBranch); insilmaril@576: } else insilmaril@795: model->clearItem (lastBranch); insilmaril@576: readBranchAttr (atts); insilmaril@576: } else if (eName=="floatimage") insilmaril@576: { insilmaril@776: state=StateImage; insilmaril@776: lastImage=model->createImage (lastBranch); insilmaril@776: if (!readImageAttr(atts)) return false; insilmaril@576: } else return false; insilmaril@576: } else return false; insilmaril@576: } else if ( eName == "branch" && state == StateMapCenter) insilmaril@576: { insilmaril@576: state=StateBranch; insilmaril@776: lastBranch=model->createBranch(lastBranch); insilmaril@576: readBranchAttr (atts); insilmaril@576: } else if ( eName == "htmlnote" && state == StateBranch) insilmaril@576: { insilmaril@576: laststate=state; insilmaril@576: state=StateHtmlNote; insilmaril@576: no.clear(); insilmaril@576: if (!atts.value( "fonthint").isEmpty() ) insilmaril@576: no.setFontHint(atts.value ("fonthint") ); insilmaril@576: } else if ( eName == "frame" && (state == StateBranch||state==StateMapCenter)) insilmaril@576: { insilmaril@576: laststate=state; insilmaril@576: state=StateFrame; insilmaril@576: if (!readFrameAttr(atts)) return false; insilmaril@576: } else if ( eName == "xlink" && state == StateBranch ) insilmaril@576: { insilmaril@576: state=StateBranchXLink; insilmaril@576: if (!readXLinkAttr (atts)) return false; insilmaril@576: } else if ( eName == "branch" && state == StateBranch ) insilmaril@576: { insilmaril@776: lastBranch=model->createBranch(lastBranch); insilmaril@576: readBranchAttr (atts); insilmaril@576: } else if ( eName == "html" && state == StateHtmlNote ) insilmaril@576: { insilmaril@576: state=StateHtml; insilmaril@576: htmldata="<"+eName; insilmaril@576: readHtmlAttr(atts); insilmaril@576: htmldata+=">"; insilmaril@576: } else if ( state == StateHtml ) insilmaril@576: { insilmaril@576: // accept all while in html mode, insilmaril@576: htmldata+="<"+eName; insilmaril@576: readHtmlAttr(atts); insilmaril@576: htmldata+=">"; insilmaril@576: } else insilmaril@576: return false; // Error insilmaril@576: return true; insilmaril@576: } insilmaril@576: insilmaril@576: bool parseVYMHandler::endElement ( const QString&, const QString&, const QString &eName) insilmaril@576: { insilmaril@576: /* Testing insilmaril@660: cout << "endElement state=" <"; insilmaril@576: if (eName=="html") insilmaril@576: { insilmaril@576: state=StateHtmlNote; insilmaril@576: htmldata.replace ("

","
"); insilmaril@576: no.setNote (htmldata); insilmaril@776: lastBranch->setNoteObj (no); insilmaril@576: } insilmaril@576: break; insilmaril@576: default: insilmaril@576: break; insilmaril@576: } insilmaril@576: state=stateStack.takeLast(); insilmaril@576: return true; insilmaril@576: } insilmaril@576: insilmaril@576: bool parseVYMHandler::characters ( const QString& ch) insilmaril@576: { insilmaril@761: //cout << "characters \""<addProgressValue ((float)branchesCounter/branchesTotal); insilmaril@749: insilmaril@776: lastMI=lastBranch; insilmaril@776: insilmaril@756: if (!readOOAttr(a)) return false; insilmaril@576: insilmaril@576: if (!a.value( "scrolled").isEmpty() ) insilmaril@785: lastBranch->toggleScroll(); insilmaril@779: // (interesting for import of KDE bookmarks) insilmaril@785: insilmaril@786: /* if (!a.value( "frameType").isEmpty() ) FIXME-3 insilmaril@576: lastOO->setFrameType (a.value("frameType")); //Compatibility 1.8.1 insilmaril@576: insilmaril@785: */ insilmaril@576: if (!a.value( "incImgV").isEmpty() ) insilmaril@576: { insilmaril@576: if (a.value("incImgV")=="true") insilmaril@576: lastBranch->setIncludeImagesVer(true); insilmaril@576: else insilmaril@576: lastBranch->setIncludeImagesVer(false); insilmaril@576: } insilmaril@576: if (!a.value( "incImgH").isEmpty() ) insilmaril@576: { insilmaril@576: if (a.value("incImgH")=="true") insilmaril@576: lastBranch->setIncludeImagesHor(true); insilmaril@576: else insilmaril@576: lastBranch->setIncludeImagesHor(false); insilmaril@576: } insilmaril@576: return true; insilmaril@576: } insilmaril@576: insilmaril@777: bool parseVYMHandler::readFrameAttr (const QXmlAttributes& a) // FIXME-4 does not work if there is no lmo for treeitem insilmaril@576: { insilmaril@777: if (lastMI) insilmaril@576: { insilmaril@777: OrnamentedObj* oo=(OrnamentedObj*)(lastMI->getLMO()); insilmaril@777: if (oo) insilmaril@576: { insilmaril@777: bool ok; insilmaril@777: int x; insilmaril@777: { insilmaril@777: if (!a.value( "frameType").isEmpty() ) insilmaril@777: oo->setFrameType (a.value("frameType")); insilmaril@777: if (!a.value( "penColor").isEmpty() ) insilmaril@777: oo->setFramePenColor (a.value("penColor")); insilmaril@777: if (!a.value( "brushColor").isEmpty() ) insilmaril@777: oo->setFrameBrushColor (a.value("brushColor")); insilmaril@777: if (!a.value( "padding").isEmpty() ) insilmaril@777: { insilmaril@777: x=a.value("padding").toInt(&ok); insilmaril@777: if (ok) oo->setFramePadding(x); insilmaril@777: } insilmaril@777: if (!a.value( "borderWidth").isEmpty() ) insilmaril@777: { insilmaril@777: x=a.value("borderWidth").toInt(&ok); insilmaril@777: if (ok) oo->setFrameBorderWidth(x); insilmaril@777: } insilmaril@777: } insilmaril@777: return true; insilmaril@777: } insilmaril@777: } insilmaril@777: return false; insilmaril@576: } insilmaril@576: insilmaril@576: bool parseVYMHandler::readOOAttr (const QXmlAttributes& a) insilmaril@576: { insilmaril@780: if (lastMI) insilmaril@576: { insilmaril@576: bool okx,oky; insilmaril@585: float x,y; insilmaril@576: if (!a.value( "relPosX").isEmpty() ) insilmaril@576: { insilmaril@576: if (!a.value( "relPosY").isEmpty() ) insilmaril@576: { insilmaril@585: x=a.value("relPosX").toFloat (&okx); insilmaril@585: y=a.value("relPosY").toFloat (&oky); insilmaril@576: if (okx && oky ) insilmaril@780: lastMI->setRelPos (QPointF(x,y)); insilmaril@576: else insilmaril@576: return false; // Couldn't read relPos insilmaril@576: } insilmaril@576: } insilmaril@788: if (!a.value( "absPosX").isEmpty() ) insilmaril@576: { insilmaril@576: if (!a.value( "absPosY").isEmpty() ) insilmaril@576: { insilmaril@585: x=a.value("absPosX").toFloat (&okx); insilmaril@585: y=a.value("absPosY").toFloat (&oky); insilmaril@576: if (okx && oky ) insilmaril@780: lastMI->setAbsPos (QPointF(x,y)); insilmaril@576: else insilmaril@576: return false; // Couldn't read absPos insilmaril@576: } insilmaril@576: } insilmaril@576: if (!a.value( "url").isEmpty() ) insilmaril@780: lastMI->setURL (a.value ("url")); insilmaril@576: if (!a.value( "vymLink").isEmpty() ) insilmaril@780: lastMI->setVymLink (a.value ("vymLink")); insilmaril@576: if (!a.value( "hideInExport").isEmpty() ) insilmaril@576: if (a.value("hideInExport")=="true") insilmaril@780: lastMI->setHideInExport(true); insilmaril@576: insilmaril@576: if (!a.value( "hideLink").isEmpty()) insilmaril@576: { insilmaril@576: if (a.value ("hideLink") =="true") insilmaril@779: lastMI->setHideLinkUnselected(true); insilmaril@576: else insilmaril@779: lastMI->setHideLinkUnselected(false); insilmaril@576: } insilmaril@576: } insilmaril@576: return true; insilmaril@576: } insilmaril@576: insilmaril@576: bool parseVYMHandler::readNoteAttr (const QXmlAttributes& a) insilmaril@576: { // only for backward compatibility (<1.4.6). Use htmlnote now. insilmaril@576: no.clear(); insilmaril@576: QString fn; insilmaril@576: if (!a.value( "href").isEmpty() ) insilmaril@576: { insilmaril@576: // Load note insilmaril@576: fn=parseHREF(a.value ("href") ); insilmaril@576: QFile file (fn); insilmaril@576: QString s; // Reading a note insilmaril@576: insilmaril@576: if ( !file.open( QIODevice::ReadOnly) ) insilmaril@576: { insilmaril@576: qWarning ("parseVYMHandler::readNoteAttr: Couldn't load "+fn); insilmaril@576: return false; insilmaril@576: } insilmaril@576: QTextStream stream( &file ); insilmaril@576: QString lines; insilmaril@576: while ( !stream.atEnd() ) { insilmaril@576: lines += stream.readLine()+"\n"; insilmaril@576: } insilmaril@576: file.close(); insilmaril@576: insilmaril@576: lines =""+lines + "

"; insilmaril@576: no.setNote (lines); insilmaril@576: } insilmaril@576: if (!a.value( "fonthint").isEmpty() ) insilmaril@576: no.setFontHint(a.value ("fonthint") ); insilmaril@776: lastBranch->setNoteObj(no); insilmaril@576: return true; insilmaril@576: } insilmaril@576: insilmaril@776: bool parseVYMHandler::readImageAttr (const QXmlAttributes& a) insilmaril@576: { insilmaril@776: lastMI=lastImage; insilmaril@576: insilmaril@823: if (!readOOAttr(a)) return false; insilmaril@576: insilmaril@576: if (!a.value( "href").isEmpty() ) insilmaril@576: { insilmaril@776: // Load Image insilmaril@776: if (!lastImage->load (parseHREF(a.value ("href") ) )) insilmaril@576: { insilmaril@576: QMessageBox::warning( 0, "Warning: " , insilmaril@776: "Couldn't load image\n"+parseHREF(a.value ("href") )); insilmaril@776: lastImage=NULL; insilmaril@576: return true; insilmaril@576: } insilmaril@576: insilmaril@576: } insilmaril@576: if (!a.value( "zPlane").isEmpty() ) insilmaril@776: lastImage->setZValue (a.value("zPlane").toInt ()); insilmaril@596: float x,y; insilmaril@576: bool okx,oky; insilmaril@576: if (!a.value( "relPosX").isEmpty() ) insilmaril@576: { insilmaril@576: if (!a.value( "relPosY").isEmpty() ) insilmaril@576: { insilmaril@576: // read relPos insilmaril@585: x=a.value("relPosX").toFloat (&okx); insilmaril@585: y=a.value("relPosY").toFloat (&oky); insilmaril@576: if (okx && oky) insilmaril@777: lastImage->setRelPos (QPointF (x,y) ); insilmaril@576: else insilmaril@576: // Couldn't read relPos insilmaril@576: return false; insilmaril@576: } insilmaril@576: } insilmaril@576: insilmaril@777: //FIXME-3 if (!readOOAttr(a)) return false; insilmaril@576: insilmaril@776: if (!a.value ("originalName").isEmpty() ) insilmaril@576: { insilmaril@776: lastImage->setOriginalFilename (a.value("originalName")); insilmaril@576: } insilmaril@576: return true; insilmaril@576: } insilmaril@576: insilmaril@790: bool parseVYMHandler::readXLinkAttr (const QXmlAttributes& a) insilmaril@576: { insilmaril@576: // object ID is used starting in version 1.8.76 insilmaril@790: // (before there was beginBranch and endBranch) insilmaril@576: if (!a.value( "beginID").isEmpty() ) insilmaril@576: { insilmaril@576: if (!a.value( "endID").isEmpty() ) insilmaril@576: { insilmaril@822: TreeItem *beginBI=model->findBySelectString (a.value( "beginID")); insilmaril@822: TreeItem *endBI=model->findBySelectString (a.value( "endID")); insilmaril@790: if (beginBI && endBI && beginBI->isBranchLikeType() && endBI->isBranchLikeType() ) insilmaril@576: { insilmaril@790: XLinkItem *xli=model->createXLink (lastBranch,true); insilmaril@790: xli->setBegin ( (BranchItem*)beginBI ); insilmaril@790: xli->setEnd ( (BranchItem*)endBI); insilmaril@790: xli->activate(); insilmaril@790: insilmaril@790: if (!a.value( "color").isEmpty() ) insilmaril@576: { insilmaril@790: QColor col; insilmaril@790: col.setNamedColor(a.value("color")); insilmaril@790: xli->setColor (col); insilmaril@576: } insilmaril@790: insilmaril@790: if (!a.value( "width").isEmpty() ) insilmaril@790: { insilmaril@790: bool okx; insilmaril@790: xli->setWidth(a.value ("width").toInt (&okx, 10)); insilmaril@790: } insilmaril@790: xli->updateXLink(); insilmaril@576: } insilmaril@576: } insilmaril@576: } insilmaril@596: return true; // xLinks can only be established at the "end branch", return true insilmaril@576: } insilmaril@576: insilmaril@576: bool parseVYMHandler::readHtmlAttr (const QXmlAttributes& a) insilmaril@576: { insilmaril@576: for (int i=1; i<=a.count(); i++) insilmaril@576: htmldata+=" "+a.localName(i-1)+"=\""+a.value(i-1)+"\""; insilmaril@576: return true; insilmaril@576: } insilmaril@576: insilmaril@576: bool parseVYMHandler::readSettingAttr (const QXmlAttributes& a) insilmaril@576: { insilmaril@576: if (!a.value( "key").isEmpty() ) insilmaril@576: { insilmaril@576: if (!a.value( "value").isEmpty() ) insilmaril@721: settings.setLocalEntry (model->getDestPath(), a.value ("key"), a.value ("value")); insilmaril@576: else insilmaril@576: return false; insilmaril@576: insilmaril@576: } else insilmaril@576: return false; insilmaril@576: insilmaril@576: return true; insilmaril@576: }