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

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 {