User:Jiangxin/Patch save extra attributes outof mmfile

From FreeMind
< User:Jiangxin
Revision as of 17:23, 6 April 2006 by Jiangxin (talk | contribs) (initial)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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 {