User:Jiangxin/Patch save extra attributes outof mmfile
From FreeMind
Jump to navigationJump to search
Why this patch?
All my .mm files are version controled using CVS/SVN. What FreeMind has scratched my personal itch:
- Some attributes of FreeMind's .mm file are not suitable for version control.
- e.g., 'FOLDED' attribute saved in .mm file, makes documents changed frequently and unnecessarily.
Overview
- Save extra attributes into another file, named *.mmx
- defined three attlist.
- attributes listed in WhiteAttlist are the only attributes should be saved to files.
- attributes listed in BlackAttlist are the attributes shouldn't be saved to files.
- attributes listed in EmAttlist will be list in a single line. (a kind of EMphasis)
Attributes saved in .mmx file will be loaded when .mm file is open. Please see another patch:
Patch file
Index: freemind/freemind/main/FreeMind.java =================================================================== --- freemind/freemind/main/FreeMind.java (.../tags/RELEASE-0-8-0) (revision 2) +++ freemind/freemind/main/FreeMind.java (.../branches/WHFM-0-8-0) (working copy) @@ -86,6 +86,7 @@ private static final String DEFAULT_LANGUAGE = "en"; private HookFactory nodeHookFactory; public static final String version = "0.8.0"; + public static final String DEFAULT_CHARSET = "UTF-8"; // public static final String defaultPropsURL = "freemind.properties"; public URL defaultPropsURL; // public static Properties defaultProps; Index: freemind/freemind/main/XMLElement.java =================================================================== --- freemind/freemind/main/XMLElement.java (.../tags/RELEASE-0-8-0) (revision 2) +++ freemind/freemind/main/XMLElement.java (.../branches/WHFM-0-8-0) (working copy) @@ -258,7 +258,58 @@ */ private int parserLineNr; + private String special_attlist[]; + private void _addtoAttlist(int list, String att) + { + if (list >= special_attlist.length || list <0) + return; + this.special_attlist[list] += att; + this.special_attlist[list] += ":"; + return; + } + + private boolean _isInAttlist(int list, String att) + { + if ( list >= special_attlist.length || list <0 || special_attlist[list].length()==0 ) { + return false; + } + return this.special_attlist[list].contains(att+':'); + } + + public boolean isInWhiteAttlist(String att) + { + if ( this.special_attlist[0].length()==0 ) { + return true; + } + return _isInAttlist(0, att); + } + + public boolean isInBlackAttlist(String att) + { + return _isInAttlist(1, att); + } + + public boolean isInEmAttlist(String att) + { + return _isInAttlist(2, att); + } + + public void addtoWhiteAttlist(String att) + { + _addtoAttlist(0, att); + } + + public void addtoBlackAttlist(String att) + { + _addtoAttlist(1, att); + } + + public void addtoEmAttlist(String att) + { + _addtoAttlist(2, att); + } + /** * Creates and initializes a new XML element. * Calling the construction is equivalent to: @@ -484,6 +535,10 @@ this.children = new Vector(); this.entities = entities; this.lineNr = 0; + this.special_attlist = new String[3]; + for (int i = 0; i < 3; i++) { + special_attlist[i] = ""; + } Enumeration enumerator = this.entities.keys(); while (enumerator.hasMoreElements()) { Object key = enumerator.nextElement(); @@ -2200,9 +2256,25 @@ if (! this.attributes.isEmpty()) { Iterator enumerator = this.attributes.keySet().iterator(); while (enumerator.hasNext()) { - writer.write(' '); String key = (String) enumerator.next(); String value = (String) this.attributes.get(key); + + if ( this.isInBlackAttlist(key) ) + { + continue; + } + else if ( ! this.isInWhiteAttlist(key) ) + { + continue; + } + + writer.write(' '); + + if ( this.isInEmAttlist(key) ) + { + writer.write("\n\t"); + } + writer.write(key); writer.write('='); writer.write('"'); this.writeEncoded(writer, value); Index: freemind/freemind/modes/mindmapmode/MindMapMapModel.java =================================================================== --- freemind/freemind/modes/mindmapmode/MindMapMapModel.java (.../tags/RELEASE-0-8-0) (revision 2) +++ freemind/freemind/modes/mindmapmode/MindMapMapModel.java (.../branches/WHFM-0-8-0) (working copy) @@ -49,13 +49,18 @@ import java.util.TimerTask; import java.util.Vector; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; +import org.w3c.dom.Document; + import freemind.controller.MindMapNodesSelection; import freemind.main.FreeMind; import freemind.main.FreeMindMain; @@ -414,9 +419,25 @@ return false; } try { //Generating output Stream - BufferedWriter fileout = new BufferedWriter( new OutputStreamWriter( new FileOutputStream(file) ) ); - getXml(fileout); + // TODO user can define his/her own charset. + BufferedWriter fileout = new BufferedWriter( new OutputStreamWriter( new FileOutputStream(file), FreeMind.DEFAULT_CHARSET ) ); + getXml(fileout, 0); + // Save FOLDED attrib into .mmx file... + String ext = Tools.getExtension(file.getName()); + String mmxFileName = ""; + if(!ext.equals("mm")) + { + mmxFileName = file.getName()+".mmx"; + } + else + { + mmxFileName = Tools.removeExtension(file.getName()) + ".mmx"; + } + File mmxfile = new File(file.getParent(), mmxFileName); + BufferedWriter mmxfileout = new BufferedWriter( new OutputStreamWriter( new FileOutputStream(mmxfile), FreeMind.DEFAULT_CHARSET ) ); + getXml(mmxfileout, 1); + if(!isInternal) { setFile(file); setSaved(true); @@ -440,11 +461,33 @@ /** writes the content of the map to a writer. * @param fileout * @throws IOException + * @param managed_attr =0|1|2 + * 0 (default): do not check FOLDED attribute(make all nodes folded), saved in .mm file. + * 1 : only check and save FOLDED attributes in .mmx file. + * 2 : save all attributes in one single .mm file. */ public void getXml(Writer fileout) throws IOException { + getXml(fileout, 0); + } + + public void getXml(Writer fileout, int managed_attr) throws IOException { + // TODO user can define his/her own charset. + fileout.write("<?xml version=\"1.0\" encoding=\"" + FreeMind.DEFAULT_CHARSET + "\"?>\n"); fileout.write("<map version=\""+getFrame().getFreemindVersion()+"\">\n"); - fileout.write("<!-- To view this file, download free mind mapping software FreeMind from http://freemind.sourceforge.net -->\n"); - ((MindMapNodeModel)getRoot()).save(fileout, this.getLinkRegistry()); + switch (managed_attr) + { + case 0: + fileout.write("<!-- This .mm file is CVS/SVN friendly, also has better Chinese character support. Contribute by http://www.WorldHello.net, orignal FreeMind can be found at http://freemind.sourceforge.net -->\n"); + break; + case 1: + fileout.write("<!-- .mmx files store some extra mm file attributes, which should not check in to CVS/SVN -->\n"); + break; + case 2: + default: + fileout.write("<!-- To view this file, download free mind mapping software FreeMind from http://freemind.sourceforge.net -->\n"); + break; + } + ((MindMapNodeModel)getRoot()).save(fileout, this.getLinkRegistry(), managed_attr); fileout.write("</map>\n"); fileout.close(); } Index: freemind/freemind/modes/NodeAdapter.java =================================================================== --- freemind/freemind/modes/NodeAdapter.java (.../tags/RELEASE-0-8-0) (revision 2) +++ freemind/freemind/modes/NodeAdapter.java (.../branches/WHFM-0-8-0) (working copy) @@ -826,7 +826,20 @@ return controller.getNodeID(this); } + /** + * @param writer + * @param registry + * @param managed_attr =0|1|2 + * 0 (default): do not check FOLDED attribute(make all nodes folded), saved in .mm file. + * 1 : only check and save FOLDED attributes in .mmx file. + * 2 : save all attributes in one single .mm file. + * @return + */ public XMLElement save(Writer writer, MindMapLinkRegistry registry) throws IOException { + return save(writer, registry, 0); + } + + public XMLElement save(Writer writer, MindMapLinkRegistry registry, int managed_attr) throws IOException { XMLElement node = new XMLElement(); // if (!isNodeClassToBeSaved()) { @@ -863,8 +876,28 @@ } } - if (isFolded()) { - node.setAttribute("FOLDED","true"); } + // do not check FOLDED attribute, save all nodes as Folded, except root and leaf. + node.addtoEmAttlist("TEXT"); + switch (managed_attr) + { + case 0: + if (!isRoot() && !isLeaf()) { + node.setAttribute("FOLDED","true"); + } + node.addtoBlackAttlist("CREATED"); + node.addtoBlackAttlist("MODIFIED"); + break; + case 1: + node.addtoWhiteAttlist("ID"); + node.addtoWhiteAttlist("FOLDED"); + node.addtoWhiteAttlist("CREATED"); + node.addtoWhiteAttlist("MODIFIED"); + case 2: + default: + if (isFolded()) { + node.setAttribute("FOLDED","true"); + } + } // fc, 17.12.2003: Remove the left/right bug. // VVV save if and only if parent is root. @@ -950,7 +983,7 @@ //recursive for (ListIterator e = childrenUnfolded(); e.hasNext();) { NodeAdapter child = (NodeAdapter) e.next(); - child.save(writer, registry); + child.save(writer, registry, managed_attr); } node.writeClosingTag(writer); } else {