X-Git-Url: https://git.sven.stormbind.net/?a=blobdiff_plain;f=src%2Fxml-freemind.cpp;fp=src%2Fxml-freemind.cpp;h=12bf161d85fba5e5617577ccf37272b5fe426bfe;hb=d483bd8e6523c23c6f1d8908a2e0611c2bc9ff4f;hp=0000000000000000000000000000000000000000;hpb=7dfa3fe589d1722d49681f42cdb0bf1e6efb5223;p=sven%2Fvym.git diff --git a/src/xml-freemind.cpp b/src/xml-freemind.cpp new file mode 100644 index 0000000..12bf161 --- /dev/null +++ b/src/xml-freemind.cpp @@ -0,0 +1,382 @@ +#include "xml-freemind.h" + +#include +#include + +#include "branchitem.h" +#include "misc.h" +#include "vymmodel.h" + +extern Settings settings; +extern QString vymVersion; + +bool parseFreemindHandler::nodeLikeState() +{ + if (state == StateCenter || state == StateMainNode || state == StateNode) + return true; + else + return false; +} + +bool parseFreemindHandler::startDocument() // FIXME-3 import not complete yet +{ + errorProt = ""; + state = StateInit; + stateStack.clear(); + stateStack.append(StateInit); + isVymPart = false; + return true; +} + +QString parseFreemindHandler::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 parseFreemindHandler::startElement(const QString &, const QString &, + const QString &eName, + const QXmlAttributes &atts) +{ + QColor col; + /* Testing + if (eName.contains("node")) + qDebug() << "startElement: <" << eName + << "> state=" << state + << " laststate=" << stateStack.last(); + //<< " loadMode=" << loadMode + //<<" line=" << QXmlDefaultHandler::lineNumber(); + */ + + stateStack.append(state); + if (state == StateInit && (eName == "map")) { + state = StateMap; + if (!atts.value("version").isEmpty()) { + QString v = "0.9.0"; + if (!versionLowerOrEqual(atts.value("version"), v)) + QMessageBox::warning( + 0, "Warning: Version Problem", + "

Freemind map is newer than version " + v + + "

" + "

The map you are just trying to load was " + "saved using freemind " + + atts.value("version") + + ". " + "Your version of vym can parse freemind " + + v + "."); + } + // Create mapcenter + model->clear(); + mapCenter = model->createMapCenter(); + lastBranch = mapCenter; + + // Create two hidden branches, because Freemind has no relative + // positioning for mainbranches + mainBranchLeft = model->createBranch(lastBranch); + mainBranchRight = model->createBranch(lastBranch); + + mainBranchLeft->setRelPos(QPointF(-200, 0)); + mainBranchLeft->setHeadingPlainText(" "); + model->emitDataChanged(mainBranchLeft); + + mainBranchRight->setRelPos(QPointF(200, 0)); + mainBranchRight->setHeadingPlainText(" "); + model->emitDataChanged(mainBranchRight); + } + else if (eName == "attribute_registry" && state == StateMap) { + state = StateAttributeRegistry; + } + else if (eName == "attribute_name" && state == StateAttributeRegistry) { + state = StateAttributeName; + } + else if (eName == "attribute_value" && state == StateAttributeName) { + state = StateAttributeValue; + } + else if (eName == "node" && state == StateMap) { + state = StateCenter; + lastBranch = mapCenter; + readNodeAttr(atts); + } + else if (eName == "node" && state == StateCenter) { + state = StateMainNode; + lastBranch = model->createBranch(lastBranch); + readNodeAttr(atts); + } + else if (eName == "node" && (state == StateNode || state == StateMainNode)) { + state = StateNode; + lastBranch = model->createBranch(lastBranch); + readNodeAttr(atts); + } + else if (eName == "properties") { + } + else if (eName == "map_styles") { + } + else if (eName == "font" && nodeLikeState()) + { + // FIXME-3 not implemented + state = StateFont; + } + else if (eName == "edge" && nodeLikeState()) + { + // FIXME-3 xlink not implemented + state = StateEdge; + } + else if (eName == "hook" && nodeLikeState()) { + state = StateHook; + } + else if (eName == "icon" && nodeLikeState()) { + state = StateIcon; + if (!atts.value("BUILTIN").isEmpty()) { + QString f = atts.value("BUILTIN"); + QString v; + if (f == "help") + v = "questionmark"; + else if (f == "messagebox_warning") + v = "freemind-warning"; + else if (f == "idea") + v = "lamp"; + else if (f == "button_ok") + v = "hook-green"; + else if (f == "button_cancel") + v = "cross-red"; + else if (f.contains("full-")) + v = f.replace("full-", "freemind-priority-"); + else if (f == "back") + v = "freemind-back"; + else if (f == "forward") + v = "freemind-forward"; + else if (f == "attach") + v = "freemind-attach"; + else if (f == "ksmiletris") + v = "smiley-good"; // + else if (f == "clanbomber") + v = "freemind-clanbomber"; + else if (f == "desktop_new") + v = "freemind-desktopnew"; + else if (f == "flag") + v = "freemind-flag"; + else if (f == "gohome") + v = "freemind-gohome"; + else if (f == "kaddressbook") + v = "freemind-kaddressbook"; + else if (f == "knotify") + v = "freemind-knotify"; + else if (f == "korn") + v = "freemind-korn"; + else if (f == "Mail") + v = "freemind-mail"; + else if (f == "password") + v = "freemind-password"; + else if (f == "pencil") + v = "freemind-pencil"; + else if (f == "stop") + v = "freemind-stop"; + else if (f == "wizard") + v = "freemind-wizard"; + else if (f == "xmag") + v = "freemind-xmag"; + else if (f == "bell") + v = "freemind-bell"; + else if (f == "bookmark") + v = "freemind-bookmark"; + else if (f == "penguin") + v = "freemind-penguin"; + else if (f == "licq") + v = "freemind-licq"; + else + qWarning() << "parseFreemindHandler: Unknown icon found: " << f; + + lastBranch->activateStandardFlagByName(v); + } + } + else if (eName == "arrowlink" && nodeLikeState()) { + state = StateArrowLink; + } + else if (eName == "cloud" && nodeLikeState()) { + state = StateCloud; + } + else if (eName == "richcontent" && nodeLikeState()) { + state = StateRichContent; + return readRichContentAttr(atts); + } + else if (eName == "html" && state == StateRichContent) { + state = StateHtml; + htmldata = "<" + eName; + readHtmlAttr(atts); + htmldata += ">"; + } + else if (eName == "text" && state == StateHook) { + state = StateText; + } + else if (state == StateHtml) { + // accept all while in html mode, + htmldata += "<" + eName; + readHtmlAttr(atts); + htmldata += ">"; + } + else { + // Usually we would return an error here + // In order to not break with every new element in FreeMind or + // FreePlane, better ignore the new element for now + state = StateUnknown; + qWarning() + << "parseFreemindHandler: Unknown element found and ignoring:: " + << eName; + } + return true; +} + +bool parseFreemindHandler::endElement(const QString &, const QString &, + const QString &eName) +{ + /* Testing + QString h; + lastBranch ? h = lastBranch->getHeadingPlain() : h = ""; + if (eName.contains("node")) + qDebug() << "endElement state=" << state << " lastBranch=" << h; + */ + + switch (state) { + case StateMap: + // Freemind does not have the two "extra" mainbranches used here, + // so we have to update mapcenter + model->emitDataChanged(mapCenter); + + // Remove helper branches, if not needed + if (mainBranchLeft->childCount() == 0) + model->deleteItem(mainBranchLeft); + if (mainBranchRight->childCount() == 0) + model->deleteItem(mainBranchRight); + break; + case StateCenter: + case StateMainNode: + case StateNode: + model->emitDataChanged(lastBranch); + lastBranch = (BranchItem *)lastBranch->parent(); + if (lastBranch) + lastBranch->setLastSelectedBranch(0); + else + qWarning() << "xml-vym: lastBranch == nullptr"; + break; + case StateRichContent: + if (!htmldata.isEmpty()) { + vymtext.setAutoText(htmldata); + if (htmlPurpose == Node) + lastBranch->setHeading(vymtext); + else if (htmlPurpose == Note) + lastBranch->setNote(vymtext); + } + break; + case StateHtml: + htmldata += ""; + if (eName == "html") { + htmldata = htmldata.replace("

", "
"); + htmldata = htmldata.replace("\\n

", "

"); + } + break; + default: + break; + } + state = stateStack.takeLast(); + return true; +} + +bool parseFreemindHandler::characters(const QString &ch) +{ + //qDebug() << "characters \"" << qPrintable(ch) << "\" state=" << state; + + QString ch_org = quoteMeta(ch); + QString ch_simplified = ch.simplified(); + if (ch_simplified.isEmpty()) + return true; + + switch (state) { + case StateInit: + break; + case StateMap: + break; + case StateNode: + break; + case StateCloud: + break; + case StateEdge: + break; + case StateIcon: + break; + case StateArrowLink: + break; + case StateFont: + break; + case StateHook: + break; + case StateText: + lastBranch->setNote(ch_simplified); + break; + case StateHtml: + htmldata += ch_org; + break; + case StateUnknown: + break; + default: + return false; + } + return true; +} + +QString parseFreemindHandler::errorString() +{ + return "the document is not in the Freemind file format"; +} + +bool parseFreemindHandler::readNodeAttr(const QXmlAttributes &a) +{ + if (state == StateMainNode) + { + // Freemind has a different concept for mainbranches + // Move either to left or right side of mapcenter + if (!a.value("POSITION").isEmpty()) { + if (a.value("POSITION") == "left") + model->relinkBranch(lastBranch, mainBranchLeft); + else if (a.value("POSITION") == "right") + model->relinkBranch(lastBranch, mainBranchRight); + } + } + + if (a.value("FOLDED") == "true") + lastBranch->toggleScroll(); + + if (!a.value("TEXT").isEmpty()) { + lastBranch->setHeadingPlainText( + a.value("TEXT")); // FIXME-3 what about RT? + // model->setHeading (a.value ("TEXT"), lastBranch); + } + + if (!a.value("COLOR").isEmpty()) + lastBranch->setHeadingColor(QColor(a.value("COLOR"))); + + if (!a.value("LINK").isEmpty()) + lastBranch->setURL(a.value("LINK")); + return true; +} + +bool parseFreemindHandler::readRichContentAttr(const QXmlAttributes &a) +{ + if (a.value("TYPE") == "NODE") + htmlPurpose = Node; + else if (a.value("TYPE") == "NOTE") + htmlPurpose = Note; + else { + htmlPurpose = Unknown; + qWarning() + << "parseFreemindHandler: Unknown purpose of richContent found: " + << a.value("TYPE"); + ; + // FIXME-3 Usually we would stop here, ignore for now + // return false; + } + return true; +}